迭代器 生成器 比较说明

参考文档

1.迭代器 Iterator

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

可以直接作用于for 循环的对象统称为可迭代对象:Iterable
判断是否是Iterable对象


>>> from collections.abc import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance({}, Iterable)
True
>>> isinstance('abc', Iterable)
True
>>> isinstance((x for x in range(10)), Iterable)
True
>>> isinstance(100, Iterable)
False

判断是否是迭代器的方法:

>>> from collections.abc import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
False

说明:真正去构建迭代器的情况很少,大多数情况下在类定义中__getitem__方法使元素边的可迭代,其他的交给迭代器协议。

2.生成器 generator

概念:在Python中,这种一边循环一边计算的机制,称为生成器:generator。

创建一个generator:
(1)把一个列表生成式的[] 改成() ,就创建了一个generator

[ ] list
( ) generator

>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>
  • 使用next(g)获取下一个返回值
    注意: generator保存的是算法,每次调用next(g) ,就计算出g 的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration 的错误。

  • 可以使用for循环迭代下一个元素

>>> g = (x * x for x in range(10))
>>> for n in g:
...     print(n)
... 
0
1
4
9
16
25
36
49
64
81

(2) 如果一个函数定义中包含yield 关键字,那么这个函数就不再是一个普通函数,而是一个generator函数,调用一个generator函数将返回一个generator.

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return 'done'

说明: generator函数和普通函数的执行流程不一样。普通函数是顺序执行,遇到return 语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next() 的时候执行,遇到yield 语句返回,再次执行时从上次返回的yield 语句处继续执行。

二者区别: 来源

1.迭代器是访问容器的一种方式,容器已经出现了(譬如列表转为迭代器,列表里的元素已经确定了),我们只是从已有元素拓印出一份副本,只为我们此次迭代使用。而生成器则是自己生成元素。
——也就是前者是从有到有的复制,后者是从无到有
2.在用法上生成器只需要简单函数写法,配合yield就能实现。而迭代器真正开发中很难使用到,我们可以把生成器看做python给我们提供的特殊接口实现的迭代器。

---------------------------------------------简单理解-----------------------------------
迭代:是一种操作,逐个从集合获取元素的过程即为迭代。

可迭代/可迭代对象Iterable:是一种特性,简单来说就是可以for循环的对象(列表、元组、字典、字符串等)。

1.迭代器Iterator:支持next()操作的对象,可以使用iter()生成迭代器。
特性:

  • 从头开始,一个一个返回
  • 不能提前知道迭代器的长度
  • 当所有元素都返回后再用next()获取的时候报异常错误StopIteration。

注意: listdictstr 虽然是Iterable ,却不是Iterator。但是可以使用iter()把他们变为可迭代对象。

2.生成器generator:一种特殊的迭代器。
生成器形成方式:

  • [ ] 变为 ( ) 例子:g = (x * x for x in range(10))
  • 函数里带yield(记住程序执行位置)

两者区别

  • 生成器是生成元素的,迭代器是访问集合元素的一种方式。
  • 迭代器是一种支持next()操作的对象,迭代器输出生成器的内容。
  • 迭代器对象表示一个数据流,可看作有序序列。不知道长度,但是可以通过next()获取下一个元素。