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循环的数据类型有以下几种:
可直接作用于for循环的对象统称为可迭代对象:Iterable
可使用next()函数调用并不断返回下一个值得对象称为迭代器:Iterator
Iterator对象表示一个数据流,Iterator对象可以被next()
函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration
错误,Iterator表示一个惰性计算的序列。
集合数据类型如list
、dict
、str
等是Iterable
但不是Iterator
,不过可以通过iter()
函数获得一个Iterator
对象。