python生成器
why:为什么要使用生成器
比如需要创建一个列表的时候,列表容量肯定有限,而且如果不需要访问后面的元素的话,列表后面的空间都浪费了。所以需要一种可以按照某种算法计算出列表元素的方法。
这种一边循环一边计算的机制就是生成器(generator),即,generator保存的是算法
好处:使用生成器可以支持延迟操作,延迟操作就是指在需要的时候可以产生结果,而不是立刻产生结果。
what:什么是生成器
原理:就是在for循环中不断计算出下一个元素,并在适当的条件结束for循环
生成器包括:
生成器表达式:
与列表生成式类似,把它的
[]
改成()
就创建了一个生成器不同的是,列表生成器一次就构建一个结果列表,生成器是按需产生结果的一个对象
生成器函数:
与正常函数定义类似,但在返回的时候不是用的return,而是用的yield。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,保留足够的信息,以便下次从它离开的地方继续执行。
when:什么时候使用生成器
当具有推算规则,可以从第一个元素,推算出后续任意元素的逻辑时,就可以使用生成器
how:怎么使用生成器
生成器每次调用next()
就计算出下一个元素的值,直到计算到最后一个元素,没有更多元素时,抛出StopIteration
错误
不过一般不用next()
,一般用的是for循环,因为generator也是可迭代对象
生成器表达式
[x for x in range(1,10)] # 列表生成式 g = (x for x in range(1,10)) # 生成器,可以使用g.next()访问下一元素 for n in g: # 循环的方式访问生成器 print n
生成器函数
注意,generator和函数的执行流程的区别:
函数是顺序执行,遇到return或最后一行函数语句就返回。
generator是每次调用
next()
的时候执行,遇到yield
就返回,再次执行就从上次返回的yield
处继续执行。如果是在循环中不断调用yield
例子,比如要打印斐波那契数列:
函数实现:
def fib(max): n, a, b = 0, 0, 1 while n < max: print b a, b = b, a+b n += 1 print fib(6)
生成器实现:
def fib(max): n, a, b = 0, 0, 1 while n < max: yield b # 仅仅将print或return改成了yield a, b = b, a + b n += 1 print fib(6) # <generator object fib at 0x103d74460> for n in fib(6): print n