生成器:1.只有在调用时才会生成相应的数据2.只记录当前位置
只有一个__next__()方法 next()
1 #列表生成式: 2 [x*2 for x in range(10)] 3 print([x*2 for x in range(10)]) 4 #生成器: 5 g = (x*2 for x in range(10)) 6 print(g)#output:<generator object <genexpr> at 0x000001FF205E93B8>
斐波那契数列:
1 def fib(max): 2 n, a, b = 0, 0, 1 3 while n<max: 4 yield b 5 a, b = b, a+b 6 n = n + 1 7 return "-----done-----" 8 9 g = fib(6) 10 while True: 11 try: 12 x = next(g) 13 print("g:",x) 14 except StopIteration as e: 15 print("Generater return value:",e.value) 16 break
函数是顺序执行,遇到return语句或者最后一行函数语句就返回。
而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,
再次执行时从上次返回的yield语句处继续执行。yield相当于一个“断点”。
生成器并行:
1 #Accounting:生产者生产包子同时分给两个人 2 import time 3 def consumer(name): 4 print("%s准备吃包子"%name) 5 while True: 6 baozi = yield 7 print("包子%s来了,被%s吃了"%(baozi,name)) 8 9 10 def producer(name): 11 c = consumer("A")#生成两个消费者 12 c2 = consumer("B") 13 c.__next__()#初始化,准备好吃包子 14 c2.__next__() 15 print("包子准备!!!") 16 for i in range(10):#生产者循环10次,每次生产两个包子分给消费者 17 time.sleep(1) 18 print("做好了两个包子了") 19 c.send(i)#send()函数唤醒yield,并向yield传递参数 20 c2.send(i) 21 producer("sugar")
迭代器:可以被next()
函数调用并不断返回下一个值的对象称为迭代器:Iterator
可以直接作用于for循环的数据类型有以下几种:
一类是集合数据类型,如list、tuple、dict、set、str等;
一类是generator,包括生成器和带yield的generator function。
这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。
可以使用isinstance()判断一个对象是否是Iterable对象:
1 from collections import Iterable 2 isinstance([], Iterable)#output:True
凡是可作用于for循环的对象都是Iterable类型;
凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;
集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象
1 from collections import Iterable 2 isinstance(iter([]), Iterator)#output:True
生成器本质上属于的迭代器。