在編程中咱們常常會用到列表,之前使用列表時須要聲明和初始化,在數據量比較大的時候也須要把列表完整生產出來,例如要存放1000給數據,須要準備長度1000的列表,這樣計算機就須要準備內存放置這個列表,在Python中,這種一邊循環一邊計算的機制,稱爲生成器:generator,這個功能在列表使用時比較節省空間,使用方法:編程
g=(i*2 for i in range(10)) data=g.__next__() print(d)
取列表時data=g.__next__(),此時纔去生成。併發
應用:生成斐波拉契數列函數
def fig(num): n,a,b=0,0,1 while n<num: yield b a,b=b,a+b n+=1 return 'done'
fig(10) 定義長度爲10的數列spa
fig(10) for i in range(10): try: x=next(g) print(x) except StopIteration as e: print('error %s' % e.value) break
運行結果:
1
1
2
3
5
8
13
21
34
55線程
這裏,最難理解的就是generator和函數的執行流程不同。函數是順序執行,遇到return
語句或者最後一行函數語句就返回。而變成generator的函數,在每次調用next()
的時候執行,遇到yield
語句返回,再次執行時從上次返回的yield
語句處繼續執行。code
還可經過yield實如今單線程的狀況下實現併發運算的效果blog
import time def customer(name): print('%s要吃包子' %name) while True: baozi=yield print('%s包子來了,很快就被%s吃了' %(baozi,name) ) return '出錯了' #拋出異常 def producter(name,student,num): g=customer(student) #**要吃包子 g.__next__() print('%s廚師瞭解到%s要吃包子,開始作包子' %(name,student)) for i in range(num): time.sleep(1) #用時1秒 g.send('韭菜餡') #包子作好,送給學生 print('包子賣完了') #張廚師,學生今天中午吃包子,用10斤面作20個包子 producter('張廚師','學生',10)
運行結果:內存
學生要吃包子
張廚師廚師瞭解到學生要吃包子,開始作包子
韭菜餡包子來了,很快就被學生吃了
韭菜餡包子來了,很快就被學生吃了
韭菜餡包子來了,很快就被學生吃了
韭菜餡包子來了,很快就被學生吃了
韭菜餡包子來了,很快就被學生吃了
韭菜餡包子來了,很快就被學生吃了
韭菜餡包子來了,很快就被學生吃了
韭菜餡包子來了,很快就被學生吃了
韭菜餡包子來了,很快就被學生吃了
韭菜餡包子來了,很快就被學生吃了
包子賣完了generator