本质上,生成器也是一种迭代器。但生成器只能迭代一次,因为值是在迭代过程生成,而所有的值没有保存在内存。这里先介绍下迭代器的概念,迭代器分为3部分:
iter
-
可迭代对象: python中的任意对象,只要它定义了可以返回一个迭代器iter方法,或者支持下标索引的getitem方法,那它就是一个可迭代对象。简单来说可迭代对象就是可以提供迭代器的任意对象。
-
迭代器: python中的任意对象有next方法就是一个迭代器。
-
迭代: 简单来说就是从某个地方取出一个元素的过程,像使用循环遍历一个列表这个过程就叫迭代。
了解迭代器的概念,我们再来细究生成器的原理:生成器是只能迭代一次的迭代器。大多数时候生成器都是通过函数来实现的。使用生成器“生成”一个值可以通过for循环,或者将它们传递给可以进行迭代的函数和结构。
(注:这个过程并不是return返回一个值,而是“生成”一个值,且所有值不保存在内存里面)
这里有个简单的例子:
def gen_fun():
for i in range(10):
yield(i)
先解释下以上的代码,gen_fun()其实是一个很普通的函数,但是函数中没有return语句,函数的返回值是一个生成器,我们可以使用生成器生成数值。
1、生成器通过for循环生成数值
生成器通过for循环生成数值
(注:这个案例并不实用,一次性生成大量数值占用内存资源。生成器的应用场景在于,你不想一次性计算出大量结果集分配到内存。特别是结果集还有循环的情况)
2、实例生成器对象使用next方法
从上图,可以看出生成器迭代一次仅生成一个值,迭代完抛出StopIteration异常。
3、列表生成表达式
list
总之,使用Python生成器,我们可以设计出更优美、简洁的代码,同时更加地节省内存资源,CPU更高效。
如下面是一个计算斐波那契数列的生成器,当数值很大时,我们也可以不用担心它会使用大量资源:
def Fibon(n):
a = b =1
for i in range(n):
yield a
a,b = b,a+b
生成器通过for循环生成数值
for item in Fibon(100000):
print(item)
参考文献:
http://docs.pythontab.com/interpy/Generators/Generators/ 作者 @yasoob《Intermediate Python》
http://python.jobbole.com/86258/ 可迭代对象 vs 迭代器 vs 生成器
网友评论