生成器与迭代器
2018-10-24 本文已影响0人
像小象的云
迭代器
在python中迭代器是一个带状态的对象,能在你调用next()方法的时候返回容器中的下一个值,任何实现了iter和next()(python2中实现next())方法的对象都是迭代器,iter返回迭代器自身,next返回容器中的下一个值,如果容器中没有更多元素了,则抛出StopIteration异常。
生成器
生成器其实是一种特殊的迭代器。生成器在Python中是一个非常强大的编程结构,可以用更少地中间变量写流式代码,此外,相比其它容器对象它更能节省内存和CPU。生成器是单迭代器对象,只支持一次活跃迭代。
在python中生成器就是函数体中有yield关键字的函数,函数中只要有yield,那么调用这个函数不再是执行函数体并且获取返回值,而是产生一个生成器。通过next获取生成器的元素的时候,会去执行生成器对应的函数的函数体,执行到yield为止,并且将yield后面的值作为返回值(元素值)。然后保存当前结束的位置,下次一获取生成器的元素的时候会接着上次结束位置往后执行,执行到yield.....
#gen是一个生成器
def gen(l):
for i in l:
yield i**2
list1 = [2,4,8,16]
g = gen(list1)
print(g)
print(next(g))
print(next(g))
print("**********")
for i in g:
print(i)
#执行结果
<generator object gen at 0x021884E0>
4
16
**********
64
256
可迭代对象(iterable)、迭代器(iterator)、生成器(generator)、列表/集合/字典等数据结构关系:

绝大多数容器都提供了某种方式来获取其中的每一个元素,但这并不是容器本身提供的能力,而是可迭代对象赋予了容器这种能力,当然并不是所有的容器都是可迭代的。
List,set,tuple,dict等是可迭代对象,处于打开状态的files,sockets等等也是可迭代对象,凡事可以返回一个迭代器的对象都是可迭代对象。
迭代器内部持有一个状态,该状态用于记录当前迭代所在的位置,以方便下次迭代的时候获取正确的元素。迭代器有一种具体的迭代器类型,比如list_iterator,set_iterator。可迭代对象实现了iter方法,该方法返回一个迭代器对象。
对于如下程序的之过程:
x =[1,2,3]
for i in x:
pass

列表解析,生成器表达式
l = [x**2 for x in range(5)] #列表解析
g = (x**2 for x in range(5)) #生成器表达式
print(l)
print(g)
print(type(l))
print(type(g))
d = {x:x*2 for x in range(5)} #字典解析
s = {x for x in [1,1,2,4,4,5]} #几何解析
print(d)
print(s)
#执行结果:
[0, 1, 4, 9, 16]
<generator object <genexpr> at 0x022284E0>
<class 'list'>
<class 'generator'>
{0: 0, 1: 2, 2: 4, 3: 6, 4: 8}
{1, 2, 4, 5}