生成器 只有在調用時才會生成相應的數據,只記錄當前位置
列表生成式
2 l = [x*2 for x in range(10)] 3 print(l)
執行結果: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
或者你會寫成這樣:
1 a=[] 2 for i in range(10): 3 a.append(i*2)
要創建一個generator,最簡單的就是,把一個列表生成式的 [] 改為 ()
1 g = (x * x for x in range(10)) 2 for i in g: 3 print(i)
執行結果:
0
2
4
6
8
10
12
14
16
18
generator非常強大,如果推算的算法比較復雜,用類似列表生成式的 for循環無法實現的時候,還可以用函數來實現。
比如,著名的斐波那契數列(Fibonacci),除數列從第3項開始,每一項都等於前兩項之和。
1,1,2,3,5,8,13,21,34,.....
1 def fib(max): 2 n,a,b = 0,0,1 3 while n<max: 4 print(b) 5 a, b = b,a+b 6 n +=1 # n = n+1 7 return 'done' 8 fib(8)
執行結果:
1
1
2
3
5
8
13
21
變成generator 只要把 print(b) 改為 yield b 即可。
1 def fib(max): 2 n,a,b = 0,0,1 3 while n<max: 4 # print(b) 5 yield b 6 a, b = b,a+b 7 n +=1 8 return 'done' 9 f= fib(8) 10 for i in f: 11 print(i)
也可以捕獲異常
1 while True: 2 try: 3 x= next(g) 4 print('g:',x) 5 except StopIteration as e: 6 print('Generator return value:',e.value) 7 break
generator並行,吃包子程序。
1 import time 2 def consumer(name): 3 print('%s 准備吃包子啦!'%name) 4 while True: 5 baozi = yield 6 print('[%s]包子來了,被[%s]吃了!'%(baozi,name)) 7 ''' 8 c = consumer('Jason') 9 c.__next__() 10 b1 = '鮮肉' 11 c.send(b1) 12 c.__next__() 13 ''' 14 def producer(): 15 c1 = consumer('Tim') 16 c2= consumer('Jack') 17 c1.__next__() 18 c2.__next__() 19 print('開始做包子啦!!') 20 for i in range(10): 21 time.sleep(1) 22 print('做了2個包子。') 23 c1.send(i) 24 c2.send(i) 25 26 producer()
