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()函数

 

posted @ 2020-03-14 20:55  LinBupt  阅读(249)  评论(0编辑  收藏  举报