生成器 只有在调用时才会生成相应的数据,只记录当前位置
列表生成式
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()