可迭代对象:Iterable

可以直接作用于 for 循环的对象,统称为 可迭代对象:Iterable
基本集合数据类型: list、tuple、dict、set、strgenerator皆为可迭代对象
判断方法:

>>>from collections import Iterable
>>>isinstance([], Iterable)
True
>>>isinstance(100, Iterable)
False

迭代器 iterator

可以被next()函数调用并不断返回下一个值的对象称为 迭代器: Iterator

>>> list=[1,2,3,4]
>>> it = iter(list)    # 创建迭代器对象
>>> print (next(it))   # 输出迭代器的下一个元素
1
>>> print (next(it))
2
>>>

list、tuple、dict、set、str 此类转为 Iterator需要使用iter()函数;
generator本身就是迭代器

>>>isinstance(iter([]), Iterator)
True

生成器 generator

带有 yield 的函数在 Python中称为 生成器。在调用它时,返回一个迭代器

# 创建generator方法1:将列表生成式的[] 改为 ()
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>

#为了将结果快速显示出来,可以转化为列表
>>>list(g)
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

# 创建方法2: 通过函数实现,例:Fibonacci数列。
def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b                    # 关键字是 yield
        a, b = b, a + b
        n = n+ 1
    return 'done'

generator 与 函数 的执行流程不同。函数顺序执行,遇到 return 或是运行到最后一行语句,就会返回。
genrator在每次调用 next()的时候执行,再次执行时从上次返回的yield 处继续执行。例:

def odd():
    print('step 1')
    yield (1)
    print('step 2')
    yield(2)
    print('step 3')
    yield(3)

>>> o = odd();
>>> next(o)
step 1
1
>>> next(o)
step 2
3
>>> next(o)
step 3
5
>>> next(o)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

由上可知,next()函数一直执行到抛出 StopIteration异常为止。
获取 generator的值, 因其是可以迭代的,所以可以用 for循环。

g = fib(6)
while True:
    try:
        x = next(g)
        print('g:', x)
    except StopIteration as e:
        print('Generator return value:', e.value)
        break  

g: 1
g: 1
g: 2
g: 3
g: 5
g: 8
Generator return value: done