迭代器、生成器
以下是对迭代器、生成器知识点的笔记
一、迭代器
概念:
(1)、对象必须提供一个__next__方法,执行该方法,要么返回迭代中的下一项,要么就引起一个stopiteration异常,以终止迭代(直接从海丰老师那里抄了过来)
(2)、可迭代对象就是,遵循了迭代器协议的对象就是可迭代对象。
(3)、可迭代对象实现了迭代器协议,python的内部工具(for,sum,min,max等函数)使用迭代器协议访问对象。
(字符串、列表、元组、字典、集合、文件对象)这些原本都不是可迭代对象,只不过for循环的时候调用了他们内部的__iter__方法,把他们变成了可迭代对象,并且捕获了StopInteration异常终止循环而已。
下面分别以字符串,列表,字典来写例子:
#字符串例子
a = 'abcdefg' new_a = a.__iter__() ---->通过__iter__方法将字符串变成可迭代对象。 print(new_a.__next__()) print(new_a.__next__())
#列表例子
l = ['a','b','c','d']
new_l = l.__iter__()
print(new_l.__next__())
print(new_l.__next__())
#字典例子
dic = {'a':1,'b':2,'c':3,'d':4}
new_dic = dic.__iter__()
print(new_dic.__next__()) --->字典默认打印的是key值
print(new_dic.__next__())
#输出
a
b
二、生成器
什么是生成器:
可以理解为一种数据类型,这种数据类型自动实现了迭代器协议,所以生成器就是可迭代对象
生成器分类及在python中的表现形式:
(1)、生成器函数:使用yield语句而不是return语句返回结果。
(2)、生成器表达式:类似于列表推导,但是生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表
生成器小结:
(1)、生成器是可迭代对象
(2)、实现了延迟计算,省内存
(3)、生成器本质和其他的数据类型一样,都是实现了迭代器协议。只不过生成器附加了一个延迟计算省内存的好处。
例子:
#生成器函数
def test(): for i in range(10): yield i new_test = test() print(new_test.__next__()) print(new_test.__next__()) print(new_test.__next__())
#生成器表达式
#注意,生成器表达式是以小括号()来把运算程序括起来的,而不是中括号[]
num=(i for i in range(10)) --->这里也是一个三元表达式
print(num.__next__())
print(num.__next__())
print(num.__next__())
#输出 0 1 2
注意:生成器只能遍历一次,如果要复用数据,生成器是无法完成的
生成器函数的总结:
(1)、语法上和函数类似:生成器函数和常规函数几乎一样,差别就在于使用yield语句来返回一个值,而常规函数是用return语句返回
(2)、自动实现迭代器协议:对于生成器,python会自动实现迭代器协议,以便应用到迭代背景中。由于生成器自动实现了迭代器协议,所以我们可以调用他的next方法,当没有值的时候自动产生stopiteration异常
(3)、状态挂起:生成器使用了yield语句返回一个值。yield语句挂起该生成器函数的状态,保留足够的信息,以便只有从他离开的地方继续进行
使用生成器来模拟生产者消费者模型:
#卖包子和吃包子的例子
import time
def client(name):
print("我是%s,我来吃包子。" % name)
while True:
baozi = yield
print('%s已经把%s吃了' % (name,baozi))
def server():
c = client('test')
c.__next__()
i = 0
while True:
print('店家生产了包子%s' % i)
c.send('包子%s' % i)
time.sleep(1)
i+=1
server()