迭代器&生成器
生成器
通过列表生成式可以直接创建一个列表。但是,受到内存限制,列表容量有限。若创建一个包含许多元素的列表,不仅占用很大的存储空间,如果仅需要访问前几个元素,那么后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,我们就不必创建完整的list,从而节省大量的空间。在python中,这种一遍循环一计算的机制,称为生成器:generator。
- 只有在调用的时候才会生成相应的数据
- 只记录当前位置
- 只有一个
__next__()
方法 - 可以通过yield实现单线程的并发效果
范例:
import time
def consumer(name):
print("%s开始吃包子了:"%name)
while 1:
bun=yield
print("%s吃了包子[%s]的一半" %(name,bun))
def producer(name):
c=consumer("tom")
c2=consumer("jack")
c.__next__()
c2.__next__()
print("%s开始做包子了"%name)
for i in range(10):
time.sleep(1)
print("第%s个包子做好了,分成了两半" %(i+1))
c.send(i+1)
c2.send(i+1)
producer("frank")
迭代器
可以直接作用于for循环的数据类型有以下几种:
- 集合数据类型:list、tuple、dict、set、str等
- generator,包括生成器和带yield的generator function
这些可以直接作用于for循环的对象统称为可迭代对象:Iterable
可以使用isinstance()判断一个对象是否是Iterable对象:
>>>from collcetions improt Iterable
>>>isinstance([],Iterable)
True
>>>isinstance((),Iterable)
True
>>>isinstance({},Iterable)
True
>>>isinstance('abc',Iterable)
True
>>>isinstance((for i in range(10)) ,Iterable)
True
>>>isinstance(100,Iterable)
False
生成器不但可以作用于for循环,还可以被next()函数不断调用并不断返回下一个值,直到最后抛出StopTteration错误表示无法继续返回下一个值。
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator
可以使用isintance()判断是否为迭代器对象:
>>>from collections import Iterator
>>>isinstance((x for x in range(10),Iteraor)
True
>>>isinstance([],Iteraor)
False
>>>isinstance({},Iteraor)
False
>>>isinstance('abc',Iteraor)
False
生成器都是Iterator对象,但是list、dice、str等虽然是Iterable,却不是Iterator。把它们变成Iterator可以使用iter()