python的迭代器和生成器

迭代器、生成器

以下是对迭代器、生成器知识点的笔记

一、迭代器

概念:

(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()
原文地址:https://www.cnblogs.com/xiaoqianghuihui/p/6694290.html