python3 生成器与迭代器
生成器: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
生成器本质上属于的迭代器。
优美胜于丑陋(Python 以编写优美的代码为目标)//
明了胜于晦涩(优美的代码应当是明了的,命名规范,风格相似)//
简洁胜于复杂(优美的代码应当是简洁的,不要有复杂的内部实现)//
复杂胜于凌乱(如果复杂不可避免,那代码间也不能有难懂的关系,要保持接口简洁)//
扁平胜于嵌套(优美的代码应当是扁平的,不能有太多的嵌套)//
间隔胜于紧凑(优美的代码有适当的间隔,不要奢望一行代码解决问题)//
可读性很重要(优美的代码是可读的)//
即便假借特例的实用性之名,也不可违背这些规则(这些规则至高无上)//
不要包容所有错误,除非你确定需要这样做(精准地捕获异常,不写 except:pass 风格的代码)//
当存在多种可能,不要尝试去猜测‘而是尽量找一种,最好是唯一一种明显的解决方案(如果不确定,就用穷举法)。虽然这并不容易,因为你不是 Python 之父(这里的 Dutch 是指 Guido )//
做也许好过不做,但不假思索就动手还不如不做(动手之前要细思量)//
如果你无法向人描述你的方案,那肯定不是一个好方案;反之亦然(方案测评标准)//
命名空间是一种绝妙的理念,我们应当多加利用(倡导与号召)//