經過列表生成式,咱們能夠直接建立一個列表。可是,受到內存限制,列表容量確定是有限的。並且,建立一個包含100萬個元素的列表,不只佔用很大的存儲空間,若是咱們僅僅須要訪問前面幾個元素,那後面絕大多數元素佔用的空間都白白浪費了。因此,若是列表元素能夠按照某種算法推算出來,那咱們是否能夠在循環的過程當中不斷推算出後續的元素呢?這樣就沒必要建立完整的list,從而節省大量的空間。在Python中,這種一邊循環一邊計算的機制,稱爲生成器:generator。python
一、建立生成器方法一算法
把一個列表生成式的 [ ] 改爲 ( )編程
生成器保存的是算法,每次調用 next(G) ,就計算出 G 的下一個元素的值,直到計算到最後一個元素,沒有更多的元素時,拋出 StopIteration 的異常。固然,這種不斷調用 next() 實在是太變態了,正確的方法是使用 for 循環,由於生成器也是可迭代對象。因此,咱們建立了一個生成器後,基本上永遠不會調用 next() ,而是經過 for 循環來迭代它,而且不須要關心 StopIteration 異常。函數
二、建立生成器方法二spa
用函數來實現,以下getNum(num)3d
1 # test.py 2 def getNum(num): 3 a,b = 0,1 4 print("*****") 5 for i in range(num): 6 print("------1-----") 7 yield b 8 print("------2-----") 9 a,b = b,a+b 10 i += 1 11 print("------3-----")
這時getNum函數,就是一個生成器。code
並不會執行協程
print("*****")
三、建立生成器方法三對象
執行到yield時,gen函數做用暫時保存,返回i的值;temp接收下次c.send("python"),send發送過來的值,c.next()等價c.send(None)blog
1 def gen(): 2 i = 0 3 while i<5: 4 temp = yield i 5 print(temp) 6 i+=1
注意:
生成器是這樣一個函數,它記住上一次返回時在函數體中的位置。對生成器函數的第二次(或第 n 次)調用跳轉至該函數中間,而上次調用的全部局部變量都保持不變。
生成器不只「記住」了它數據狀態;生成器還「記住」了它在流控制構造(在命令式編程中,這種構造不僅是數據值)中的位置。
生成器的特色: