python迭代器与生成器

Iterable—可迭代 可迭代的序列类型包括,list,str,tuple,非序列类型包括dict,file,任何类只是你定义了iter方法就会被看作为可迭代对象。

In [3]: from collections import Iterable, Iterator

In [4]: class A:
...:        def __init__(self):
...:            self.n = 0
...:        def __iter__(self):
...:            return self
...:

In [5]: a = A()

In [6]: isinstance(a, Iterable)
Out[6]: True

Iterator—迭代器 Iterator必须实现iter()和next()(python3)或next()(python2)两个方法,组成了迭代器协议。

In [13]: class yrange:
...:         def __init__(self, n):
...:             self.i = 0
...:             self.n = n
...:
...:         def __iter__(self):
...:             return self
...:
...:         def __next__(self):
...:             if self.i < self.n:
...:                 i = self.i
...:                 self.i += 1
...:                 return i
...:             else:
...:                 raise StopIteration()
...:

In [14]: it = yrange(3)

In [15]: it.__next__()
Out[15]: 0

In [16]: it.__next__()
Out[16]: 1

In [17]: it.__next__()
Out[17]: 2

In [18]: it.__next__()
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-18-a1cc91b7bc73> in <module>()
----> 1 it.__next__()

<ipython-input-13-55955e9c2cc7> in __next__(self)
13 return i
14 else:
---> 15 raise StopIteration()
16

StopIteration:

反向迭代一个序列,使用内置的reversed()函数,可以通过在自定义类上实现reversed () 方法来实现反向 迭代。

In [19]: class yrange:
...:         def __init__(self, n):
...:             self.i = 0
...:             self.n = n
...:
...:         def __iter__(self):
...:             return self
...:
...:         def __next__(self):
...:             if self.i < self.n:
...:                 i = self.i
...:                 self.i += 1
...:                 return i
...:             else:
...:                 raise StopIteration()
...:         def __reversed__(self):
...:             index = self.n - 1
...:             while index >= 0:
...:                 yield index
...:                 index -= 1
...:

In [20]: it = reversed(yrange(3))

In [21]: it.__next__()
Out[21]: 2

In [22]: it.__next__()
Out[22]: 1

In [23]: it.__next__()
Out[23]: 0

generator—生成器 生成器是一个返回迭代器对象的函数。它和普通函数看起来一样,除了它包含了yield语句,产生可以通过for循环访问的值,或者可以通过调用next方法一次访问一个值。 生成的iter()和next()方法是自动创建的。。每次next()调用时,生成器再恢复它离开的位置(它记忆语句最 后一次执行的位置和所有的数据值)

In [25]: def integer():
...:         i = 1
...:         while True:
...:             yield i
...:             i += 1
...:

In [26]: i = integer()

In [27]: i
Out[27]: <generator object integer at 0x7fb940696fc0>

In [29]: i.__next__()
Out[29]: 1

生成器—send方法,调用send()方法前,必须先调用next()方法(pep342)

In [37]: def double_input():
...:         while True:
...:             x = yield
...:             yield x * 2

In [59]: gen = double_input()

In [60]: gen.__next__()

In [61]: gen.send(4)
Out[61]: 8

In [62]: gen.send(4)

In [63]: gen.send(4)
Out[63]: 8

In [64]: gen.__next__()

In [65]: gen.send(5)
Out[65]: 10

Ref: 1.http://anandology.com/python-practice-book/iterators.html 2.官方文档