python迭代器与生成器详解迭代器与生成器详解
例子例子
老规矩,先上一个代码:
def add(s, x):
return s + x
def gen():
for i in range(4):
yield i
base = gen()
for n in [1, 10]:
base = (add(i, n) for i in base)
print list(base)
这个东西输出可以脑补一下, 结果是[20,21,22,23], 而不是[10, 11, 12, 13]。 当时纠结了半天,一直没搞懂,后来齐老师稍微
指点了一下, 突然想明白了–真够笨的,唉。。好了–正好趁机会稍微小结一下python里面的生成器。
迭代器迭代器(iterator)
要说生成器,必须首先说迭代器
区分iterable,iterator与itertion
讲到迭代器,就需要区别几个概念:iterable,iterator,itertion, 看着都差不多,其实不然。下面区分一下。
itertion: 就是迭代,一个接一个(one after another),是一个通用的概念,比如一个循环遍历某个数组。
iterable: 这个是可迭代对象,属于python的名词,范围也很广,可重复迭代,满足如下其中之一的都是iterable:
可以for循环: for i in iterable
可以按index索引的对象,也就是定义了__getitem__方法,比如list,str;
定义了__iter__方法。可以随意返回。
可以调用iter(obj)的对象,并且返回一个iterator
iterator: 迭代器对象,也属于python的名词,只能迭代一次。需要满足如下的迭代器协议
定义了__iter__方法,但是必须返回自身
定义了next方法,在python3.x是__next__。用来返回下一个值,并且当没有数据了,抛出StopIteration
可以保持当前的状态
首先str和list是iterable 但不是iterator:
In [3]: s = 'hi'
In [4]: s.__getitem__
Out[4]: <method-wrapper '__getitem__' of str object at 0x7f9457eed580>
In [5]: s.next # 没有next方法
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-5-136d3c11be25> in <module>()
----> 1 s.next
AttributeError: 'str' object has no attribute 'next'
In [6]: l = [1,2] # 同理
In [7]: l.__iter__
Out[7]: <method-wrapper '__iter__' of list object at 0x7f945328c320>
In [8]: l.next
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-8-c6f8fb94c4cd> in <module>()
----> 1 l.next
AttributeError: 'list' object has no attribute 'next'
In [9]: iter(s) is s #iter() 没有返回本身
Out[9]: False
In [10]: iter(l) is l #同理
Out[10]: False