Python生成器&迭代器

RocNg 2020-04-18

生成器:generator

在Python中一边循环一边计算的机制称为生成器。由于列表中的所有数据都会放在内存中,因此会非常消耗内存。而若仅需要访问前面几个数据,那么后面的数据占用的内存空间就被浪费了。如果列表元素能够按照某种算法推算出来,就可以在循环中不断推算出后续的元素,这样就不必创建完整的列表,从而节省大量的空间。

生成器仅仅保存了一套生成数值的算法,什么时候调用它,它什么时候开始计算一个新的值并返回。

创建generator的第一种方法:把一个列表生成式的 [ ] 改为(),就创建了一个generator

>>> L = [ x*x for x in range(1,11)]
>>> L
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
>>> G = (x*x for x in range(1,11))
>>> G
<generator object <genexpr> at 0x00000239FD73A408>

要获得生成器的返回值,可以通过next()函数一个一个打印generator的下一个返回值,当没有更多元素的时候,会抛出StopIteration的错误。

>>> next(G)
1
>>> next(G)
4
>>> next(G)
9
...
>>> next(G)
100
>>> next(G)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

也可以通过for循环,因为generator是可迭代对象

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

创建generator的第二种方法:函数定义中包含yield关键字,这个函数就不再是一个普通的函数,而是一个generator,调用函数就是创建一个生成器对象。

理解generator和函数的执行流程:函数顺序执行,遇到return语句或者最后一行函数语句就返回;generator在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处执行

>>> def odd():
...     print(‘step 1‘)
...     yield 1
...     print(‘step 2‘)
...     yield 3
...     print(‘step 3‘)
...     yield 5
...
>>> 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

>>> for n in odd():
... print(n)
...
step 1
1
step 2
3
step 3
5

迭代器

可以直接作用于for循环的数据类型有以下几种:

  • 集合数据类型:list、tuple、dict、set、str等
  • generator,包括生成器和带有yield的generator function

可直接作用于for循环的对象统称为可迭代对象:Iterable

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

Iterator对象表示一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误,Iterator表示一个惰性计算的序列。

集合数据类型如listdictstr等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。

相关推荐