1、迭代器
迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个 Stopiteration异常,以终止迭代(只能往后走不能往前退)
可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义一个_iter_()方法)
协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(for循环,sum,min函数等)使用 迭代器协议访问对象
2、for循环的本质
循环所有对象,全都是使用迭代器协议
(字符串、列表、元组、集合、文件对象)这些都不是可迭代对象,只不过在for循环时,调用了他们内部的 _iter_方法,把他们变成了可迭代对象
然后for循环调用可迭代对象的_next_方法去取值,而且for循环会捕捉Stopiteraton异常,以终止迭代。
3.序列类型
字符串、列表、元组都有下表,可用index访问。即可以用while循环 但非序列类型:字典、集合、文件对象无法用index访问,所以用for。
for循环就是基于迭代器协议提供了一个统一的可以遍历所有对象的方法,即在遍历之前,先调用对象的 _iter_方法将其转换成一个迭代器,
然后使用迭代器协议去实现循环访问,这样所有的对象就都可以通过for循环遍历了。
4 生成器
4.1一种数据类型,这种数据类型自动实现迭代器协议(其他的数据类型需要调用自己的_iter_方法),所以生成器就是可迭代对象。
4.2生成器在python中有两种不同的表达方式
(1)生成器函数 def test(): yield 1 yield 2 yield 3 g=test() # 不需要调用_iter_方法 print(g.__next__()) print(g.__next__()) print(g.__next__())
(1)生成器表达式 三元表达式 # name='alex' name='linhf' res='SB' if name == 'alex' else '帅哥' (if name == 'alex'是一元,res='SB'是二元,else '帅哥' 是三元) print(res)
列表解析 egg_list=[] for i in range(10): egg_list.append('鸡蛋%s'%i) print(egg_list) 可以改写为 l=['鸡蛋%s'%i for i in range(10)] print(l)
laomuji=('鸡蛋%s'%i for i in range(10)) # 生成器表达式 print(laomuji) print(laomuji.__next__()) print(laomuji.__next__()) print(laomuji.__next__()) print(laomuji.__next__())
4.3 总结
(1)把列表解析的[ ]换成()得到的就是生成器表达式
(2)列表解析与生成器表达式都是一种便利的编程方式,只不过生成器表达式更节省内存
(3)python不但使用迭代器协议,让for循环变得更加通用,大部分内置函数,也是使用迭代器协议访问对象的。例如,sum函数是python的内置函数,该函数使用迭代器协议访问对象,而生成器实现了迭代器协议。