首页 > 代码库 > 迭代器和生成器
迭代器和生成器
from collections import Iterator def test(): print(‘one‘) yield 1 #return 1 g=test() print(g) #生成器的内存地址 print(isinstance(g,Iterator)) #判断是否是迭代器
一 什么是迭代器协议
1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退)
2.可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义一个__iter__()方法)
3.协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(如for循环,sum,min,max函数等)使用迭代器协议访问对象。
二 python中强大的for循环机制
for循环的本质:循环所有对象,全都是使用迭代器协议。
(字符串,列表,元组,字典,集合,文件对象)这些都不是可迭代对象,只不过在for循环式,调用了他们内部的__iter__方法,把他们变成了可迭代对象
然后for循环调用可迭代对象的__next__方法去取值,而且for循环会捕捉StopIteration异常,以终止迭代
l=[‘a‘,‘b‘,‘c‘] diedai_l=l.__iter__() print(diedai_l.__next__()) print(diedai_l.__next__()) print(diedai_l.__next__()) #for循环l本质就是遵循迭代器协议的访问方式,先调用diedai_l=l.__iter__()方法,或者直接diedai_l=iter(l),然后依次执行diedai_l.next(),直到for循环捕捉到StopIteration终止循环 #for循环所有对象的本质都是一样的原理
用while去模拟for循环做的事情
diedai_l=l.__iter__()
while True:
try:
print(diedai_l.__next__())
except StopIteration:#异常捕捉,有异常跳出循环
print(‘迭代完毕了,循环终止了‘)
break
三 迭代器
可迭代的:只要对象本身有__iter__方法,那它就是可迭代的
执行对象下的__iter__方法,得到的结果就是迭代器
为什么要用迭代器:
优点
1:迭代器提供了一种不依赖于索引的取值方式,这样就可以遍历那些没有索引的可迭代对象了(字典,集合,文件)
2:迭代器与列表比较,迭代器是惰性计算的,更节省内存
缺点:
1:无法获取迭代器的长度,使用不如列表索引取值灵活
2:一次性的,只能往后取值,不能倒着取值
查看可迭代对象与迭代器对象
from collections import Iterable,Iterator #导入查看可迭代对象与迭代器对象的模块
s=‘hello‘
f=open(‘a.txt‘)
查看是否是可迭代的
print(isinstance(s,Iterable)) #查看是否可迭代,返回一个布尔值
print(isinstance(f,Iterable)) #查看是否可迭代,返回一个布尔值
查看是否是迭代器
print(isinstance(s,Iterator))
print(isinstance(f,Iterator)) #文件本身就是迭代器
协程函数
如果在一个函数内部yield的使用方式是表达式形式的话,如x=yield,那么该函数成为协程函数
def eater(name): food_list=[] while True: food=yield food_list food_list.append(food) #因为有yied
e=eater(‘钢蛋‘) #一个生成器的内存地址 print(next(e)) #初始化迭代器
print(e.send(‘包子‘)) print(e.send(‘韭菜馅包子‘)) print(e.send(‘大蒜包子‘))
四 生成器
生成器分类及在python中的表现形式:(Python有两种不同的方式提供生成器)
1.生成器函数:常规函数定义,但是,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行
2.生成器表达式:类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表
为何使用生成器之生成器的优点
Python使用生成器对延迟操作提供了支持。所谓延迟操作,是指在需要的时候才产生结果,而不是立即产生结果。这也是生成器的主要好处。
生成器小结:
1.是可迭代对象
2.实现了延迟计算,省内存
3.生成器本质和其他的数据类型一样,都是实现了迭代器协议,只不过生成器附加了一个延迟计算省内存的好处,其余的可迭代对象可没有这点好处。
生成器与return有何区别?
return只能返回一次函数就彻底结束了,而yield能返回多次值
yield到底干了什么事情:
1.yield把函数变成生成器,生成器就是迭代器
用return返回值能返回一次,而yield返回多次
函数在暂停以及继续下一次运行时的状态是由yield保存
迭代器和生成器