迭代器(Iterator)和生成器(Generator)是在python2.2引入的;本小节将使用白话文来介绍迭代器与生成器,白话未必准确严谨,但是更加简明形象;重在理解与体会。
用白话来说,迭代器协议就是由2部分组成:前者是“生产者”,后者是“消费者”。生产者说:“我知道如何来提供数据,我负责的就是准备好要提供的数据,然后每次提供一个”;消费者书,“小爷我就是吃货,请生产者每次提供一个数据给我吃,如果你的数据被我吃光了,要跟我说下你没有数据了。”
生产者说:“好哒”;于是乎,请看下例:
#coding=utf-8 def func(): yield 33 yield 32 yield 22 yield 101 a = func() # <generator object func at 0x10a647460> print a.next() # 会输出33 print a.next() # 会输出32 print a.next() # 会输出22 print a.next() # 会输出101 print a.next() # 没有东西可输出了,所以就报错StopIteration
上述这个简单的例子中,就涵盖了迭代器(Iterator)和生成器(Generator)。上例中的变量a就是迭代器,而生成器就是构造迭代器对象的函数func。
万变不离其宗,有时只是融入了其它的知识点;如下所示,python的内置函数iter可根据有序序列对象(列表、字符串、元组)来构建一个迭代器(Iterator)对象;从而省去手动来写生成器函数。
#coding=utf-8 list_obj = range(4) # 返回[0, 1, 2, 3] it = iter( list_obj ) # 根据列表对象返回迭代器对象 print next( it ) # 输出0 next(it)等价于it.next() print next( it ) # 输出1 print next( it ) # 输出2 print next( it ) # 输出3 print next( it ) # 没有东西可输出了,所以就报错StopIteration
本小节重在帮助初学者对迭代器与生成器进行理解与体会,找感觉为目的,不以实际运用为目的,暂不做深入展开;理解这些对于日常使用python时对一些细节会有更深刻理解,比如xrange与range的区别,前者返回的是一个迭代器,后者返回的是一个列表;若传入的整数形参较大,则后者会占用太多内存、效率过低,而前者返回的是迭代器对象,则对内存的占用很小,且相对固定有限。从实用角度,只需要记住for循环中一律实用xrange即可;而经过本小节,则应对其内在有了进一步理解体会。