Python 高级特性 : 生成器
本文中代码均在IDLE中实现
如果你有任何意见或者建议,希望您能写在评论区
通过列表生成式,我们可以便捷的得到我们期望的list。生成list是需要消耗内存的,当list过大时,会浪费过多的资源。如果列表中的项可以在需要的时候生成,而不是一次性生成,也就是一边循环一边计算生成的机制,那么这个问题就可以解决。
Python就提供了这样一种边循环边计算生成的机制—生成器
创建一个生成器其实十分简单,只需要把一个列表生成式的‘[ ]’改为‘()’,即可
>>> list = [x*x for x in range(0,5)] ##创建一个列表
>>> type(list) ##显示 list 类型
<type 'list'>
----------
>>> list = (x*x for x in range(0,1)) ##创建一个生成器
>>> type(list) ##显示list类型
<type 'generator'>
现在我们拥有一个生车器,要怎么访问那?
##直接访问
>>> list
<generator object <genexpr> at 0x0000000002A7FEA0>
##返回了一段说明,意思就是这是一个生成器,保存在内存的 0x0000000002A7FEA0 位置。
##那么我们要怎样才能访问到那??
----------
>>> list.next() ##通过 next() 即可访问生成器中的下一个值
0
>>> list.next()
1
>>> list.next()
4
>>> list.next()
9
>>> list.next()
16
。。。。
>>> list.next()
Traceback (most recent call last):
File "<pyshell#54>", line 1, in <module>
list.next()
StopIteration
##当到达生成器中不能产生更多元素时,抛出错误 StopIteration(停止迭代)
----------
##正确的访问生成器的方式是,通过 for 循环迭代生成器
>>> for i in list :
print i
----
1
4
9
16
25
36
49
64
81
100
简单的生成器可以生成一组数据,但是有复杂的需求时,仅是生成器就无法满足了,我们可以将一个函数定义成一个生成器
##我们尝试一下著名的斐波那契数列,很显然利用生成器是很难解决的
##那么就编写一个函数
>>> def fib(max) :
n,a,b = 0,0,1
while n < max :
print b
a,b =b,b+a
n = n+1
>>> fib(5)
1
1
2
3
5
##很显然,这个函数一股脑的就把结果输出了,我们想要他一次输出一个,再次访问的时候输出下一个。
##只需做一个小小的改动
>>> def fib(max):
a,b,n = 0,1,0
while n < max :
yield b ##这里有变化哦
a,b = b,b+a
n = n+1
>>> fib
<function fib at 0x0000000002ECFBA8>
## yield 就是 生成器的标志,函数执行到yield时,会返回指定的值,然后记录下运行位置,再次运行时,从记录的位置开始执行。
##我们来试一试
>>> test = fib(4) ##初始化'fib'函数
>>> test.next()
1
>>> test.next()
1
>>> test.next()
2
>>> test.next()
3
>>> test.next()
##迭代结束后,无法生成更多的元素,返回‘StopIteration’错误
Traceback (most recent call last):
File "<pyshell#114>", line 1, in <module>
test.next()
StopIteration