列表生成式
list1 是一個可迭代的對象。當使用一個列表生成式來簡歷一個列表的時候,就建立了一個可迭代對象:
<<<list1 = [x*x for x in range(1, 11)]
<<<list1
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
在這裏所有的值都存在內存當中,所以並不適合大量數據。在python中,list,tuple,dict和set都是可迭代的對象,字符串也是可迭代對象。
生成器(generator)概念
引題
通過列表生成式,我們可以直接創建一個列表。但是,受到內存限制,列表容量肯定是有限的。而且,創建一個包含100萬個元素的列表,不僅佔用很大的存儲空間,如果我們僅僅需要訪問前面幾個元素,那後面絕大多數元素佔用的空間都白白浪費了。
所以,如果列表元素可以按照某種算法推算出來,那我們是否可以在循環的過程中不斷推算出後續的元素呢?這樣就不必創建完整的list,從而節省大量的空間。在Python中,這種一邊循環一邊計算的機制,稱爲生成器:generator。
生成器不會把結果保存在一個系列中,而是保存生成器的狀態,在每次進行迭代時返回一個值,直到遇到StopIteration異常結束。
生成器語法
要創建一個generator,有很多種方法。第一種方法很簡單,只要把一個列表生成式的[]改成(),就創建了一個generator:
生成器特點:
1.可迭代
2.只能讀取一次
3.實時生成數據,不全存在內存中
<<<generator = (x*x for x in range(1, 11))
<<<generator
<generator object <genexpr> at 0x000000000DD99990>
<<<next(generator)
1
<<<next(generator)
4
<<<for i in generator:
print(i)
9
16
25
36
49
64
81
100
區別·:
我們可以直接打印出list的每一個元素,
而打印出來generator的每一個元素可以通過next()函數獲得generator的下一個返回值,
這個生成器只能使用一次for循環來遍歷,之後就不能使用了
生成器函數: 在函數中如果出現了yield關鍵字,那麼該函數就不再是普通函數,而是生成器函數。
yield是一個類似return的關鍵字,只是這個函數返回的是個生成器
但是生成器函數可以生產一個無線的序列,這樣列表根本沒有辦法進行處理。
yield 的作用就是把一個函數變成一個 generator,帶有 yield 的函數不再是一個普通函數,Python 解釋器會將其視爲一個 generator。生成器函數: 在函數中如果出現了yield關鍵字,那麼該函數就不再是普通函數,而是生成器函數。
def createGenerator():
mylist = range(3)
for i in mylist:
yield i*i
mygenerator = createGenerator() # 創建一個生成器
print(mygenerator)
<generator object createGenerator at 0x000000000DD999E8>
# 打印出來顯示mygenerator是一個對象
for i in mygenerator: # 使用for調用生成器對象
print(i)
0
1
4
第一次迭代中createGenerator函數纔會執行,從開始到達yield關鍵字,然後返回yield後的值作爲第一次迭代返回的值,然後,每次執行這個函數都會繼續執行你在函數內部定義的那個循環的下一次,再返回那個值,直到沒有值可以返回的。