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

生成器本质上属于的迭代器。

 
 
 
 
 
posted @ 2019-01-23 17:20  椰汁软糖  阅读(271)  评论(0编辑  收藏  举报