Python学习之路(15)——生成器
生成器可以说是Python语言中最吸引人的特性之一。
生成器也是一种迭代器,但是只能对其迭代一次。生成器作为一种特殊的迭代器,显得更加优雅,能够在很多情况下以一种优雅而又更低内存消耗的方式简化无界(无限)序列相关的操作。它不需要像迭代器那样,需要使用__ite__()和__next__()方法,只需要使用一个 yield 关键字。
大多数时候生成器是以函数来实现的,然而它并不返回一个值,而是yield一个值。
>>> def generator_function(): for i in range(10): yield i >>> for item in generator_function(): print(item) 0 1 2 3 4 5 6 7 8 9 >>>
上面是一个生成器函数的简单例子,但这种用法并不常用。生成器最佳应用场景是,不想在同一时间将所有计算出的大量结果集分配到内存中,特别是结果集里还包含循环。
比如下面一个计算斐波那契数列的生成器:
>>> def Fibs(n): a, b = 0, 1 for i in range(n): yield b a, b = b, a + b >>> for x in Fibs(10): print(x) 1 1 2 3 5 8 13 21 34 55 >>>
再看一个例子,我们使用next()函数:
>>> def generator_function():
for i in range(3):
yield i
>>> gen = generator_function()
>>> print(next(gen))
0
>>> print(next(gen))
1
>>> print(next(gen))
2
>>> print(next(gen))
Traceback (most recent call last):
File "<pyshell#131>", line 1, in <module>
print(next(gen))
StopIteration
我们可以看到,在yield掉所有的值后,next()触发了一个StopInteration异常。这个异常告诉我们,所有的值都已经被yield完了。
生成器 vs 函数
生成器和函数的主要区别在于函数 return a value,生成器 yield a value,同时标记或者记忆 point of the yield 以便于在下次调用时从标记点恢复执行。 yield 使函数转换成生成器, 而生成器反过来又返回迭代器。
生成器表达式
生成器表达式是列表推导式的生成器版本,看起来像列表推导式,但是使用小括号“()”,而不是中括号“[]”,返回一个生成器对象,而不是列表对象。
>>> list1 = [x*x for x in range(10)] >>> list1 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] >>> >>> gen1 = (x*x for x in range(10)) >>> gen1 <generator object <genexpr> at 0x0000000003672258> >>> >>> sum(list1) 285 >>> sum(gen1) 285 >>>
浙公网安备 33010602011771号