Python3生成器与迭代器
参考:https://www.liaoxuefeng.com/wiki/1016959663602400/1017323698112640
在Python中,一边循环一边计算的机制,成为生成器:generator。
创建生成器:(列表生成式) 获取生成器的值:next() for循环(生成器也是可迭代对象)
yield关键字 每次调用next()的时候执行,遇到yield返回,再次执行时从上次返回的yield语句处继续执行
调用生成器时,首先要生成一个生成器对象,然后用next()函数不断获得下一个返回值;要想获得生成器中return语句的返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中。
1 #for循环调用生成器的内部原理,也是包含了下面这样一个while True 2 #只不过没有输出捕获的异常的值 3 while True: 4 try: 5 x = next(g) 6 print('g:', x) 7 exception StopIteration as e: 8 print('Generator return value:', e.value) 9 break
1 #send给yield前面的变量赋值 2 def bar(): 3 print('ok1') 4 count = yield 1 5 print(count) 6 print('ok2') 7 yield 2 8 b = bar() 9 10 #第一次send前如果没有调用next只能传一个None 11 b.send(None) #ok1 12 a = b.send('e') # e ok2 13 print(a) # 2 14 -------------------------------------------------- 15 a = next(b) #ok1 16 print(a) #1
基于yield可以实现协程
基于yield可以实现伪并发
1 import time 2 def consumer(name): 3 print(f'{name}准备吃包子啦!') 4 while True: 5 food = yield 6 print(f'{food}做出来了,被{name}吃了') 7 def producer(name): 8 c1 = consumer('A') 9 c2 = consumer('B') 10 next(c1) 11 c2.send(None) 12 print(f'{name}开始吃饭了啦!') 13 for i in range(10): 14 time.sleep(1) 15 print('饭做好了') 16 c1.send(f'包子{i}') 17 c2.send(f'饺子{i*2}') 18 producer('aaaa')
迭代器
可以直接作用于for循环的数据类型有以下几种:这些可以直接作用于for循环的对象统称为可迭代对象(Iterable)
一类是集合数据类型,如list、tuple、dict、set、str等
一类是generator,包括生成器和带yield的generator function
isinstance() -->用于判断a是不是b类型的一个对象
可以被next()函数调用并不断返回下一个值得对象称为迭代器:Iterator
生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator
把list、dict、str等Iterable变成Iterator可以使用iter()函数