# 完全理解Python迭代对象、迭代器、生成器

### 容器(container)

• list, deque, ….
• set, frozensets, ….
• dict, defaultdict, OrderedDict, Counter, ….
• tuple, namedtuple, …
• str

``>>> assert 1 in [1, 2, 3]      # lists >>> assert 4 not in [1, 2, 3] >>> assert 1 in {1, 2, 3}      # sets >>> assert 4 not in {1, 2, 3} >>> assert 1 in (1, 2, 3)      # tuples >>> assert 4 not in (1, 2, 3)  ``

``>>> d = {1: 'foo', 2: 'bar', 3: 'qux'} >>> assert 1 in d >>> assert 'foo' not in d  # 'foo' 不是dict中的元素  ``

``>>> s = 'foobar' >>> assert 'b' in s >>> assert 'x' not in s >>> assert 'foo' in s  ``

### 可迭代对象(iterable)

``>>> x = [1, 2, 3] >>> y = iter(x) >>> z = iter(x) >>> next(y) 1 >>> next(y) 2 >>> next(z) 1 >>> type(x) <class 'list'> >>> type(y) <class 'list_iterator'>  ``

``x = [1, 2, 3] for elem in x:     ... ``

``>>> import dis >>> x = [1, 2, 3] >>> dis.dis('for _ in x: pass')   1           0 SETUP_LOOP              14 (to 17)               3 LOAD_NAME                0 (x)               6 GET_ITER         >>    7 FOR_ITER                 6 (to 16)              10 STORE_NAME               1 (_)              13 JUMP_ABSOLUTE            7         >>   16 POP_BLOCK         >>   17 LOAD_CONST               0 (None)              20 RETURN_VALUE ``

### 迭代器(iterator)

``>>> from itertools import count >>> counter = count(start=13) >>> next(counter) 13 >>> next(counter) 14  ``

``>>> from itertools import cycle >>> colors = cycle(['red', 'white', 'blue']) >>> next(colors) 'red' >>> next(colors) 'white' >>> next(colors) 'blue' >>> next(colors) 'red'  ``

``>>> from itertools import islice >>> colors = cycle(['red', 'white', 'blue'])  # infinite >>> limited = islice(colors, 0, 4)            # finite >>> for x in limited:                          ...     print(x) red white blue red  ``

``class Fib:     def __init__(self):         self.prev = 0         self.curr = 1      def __iter__(self):         return self      def __next__(self):         value = self.curr         self.curr += self.prev         self.prev = value         return value  >>> f = Fib() >>> list(islice(f, 0, 10)) [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]  ``

Fib既是一个可迭代对象（因为它实现了 `__iter__` 方法），又是一个迭代器（因为实现了 `__next__` 方法）。实例变量 `prev``curr` 用户维护迭代器内部的状态。每次调用 `next()` 方法的时候做两件事：

1. 为下一次调用 `next()` 方法修改状态
2. 为当前这次调用生成返回结果

### 生成器(generator)

``def fib():     prev, curr = 0, 1     while True:         yield curr         prev, curr = curr, curr + prev  >>> f = fib() >>> list(islice(f, 0, 10)) [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]  ``

`fib` 就是一个普通的python函数，它特需的地方在于函数体中没有 `return` 关键字，函数的返回值是一个生成器对象。当执行 `f=fib()` 返回的是一个生成器对象，此时函数体中的代码并不会执行，只有显示或隐示地调用next的时候才会真正执行里面的代码。

``def something():     result = []     for ... in ...:         result.append(x)     return result ``

``def iter_something():     for ... in ...:         yield x``