通过列表表达式可以直接生成列表,不过列表一旦生成就需要为所有元素分配内存,有时候会很消耗资源。
所以,如果列表元素可以按照某种算法推算出来,这样就不必创建完整的list,从而节省大量的内存空间。
在Python中,这种一边循环一边计算的机制,称为生成器(Generator)。
创建列表
法一:test = range(10)print type(test)#法二:test = [item for item in range(10)]print type(test)#
创建生成器
test = (item for item in range(10))print type(test)#
生成器是一个可以自动推导后续元素的对象,为了得到其元素,我们可以直接通过 next() 方法:
test = (item for item in range(10))print type(test)print test.next()print test.next()print test.next()## 0# 1# 2
另外一种方式是用 for 可以直接迭代生成器的所有元素:
test = (item for item in range(10))print type(test)for item in test: print item## 0# 1# 2# 3# 4# 5# 6# 7# 8# 9
注意,每一次调用 next() 都使得生成器推导出下一个元素,使得生成器的元素减少:
test = (item for item in range(10))print type(test)print test.next()print test.next()#至此,生成器中只还有8个元素for index, item in enumerate(test): print index, '=', item## 0# 1# 0 = 2# 1 = 3# 2 = 4# 3 = 5# 4 = 6# 5 = 7# 6 = 8# 7 = 9
用函数创建生成器
如果函数中包含 yield ,那么该函数就变成了一个生成器。
函数类型的生成器的特点是:在每次调用 next() 的时候执行,遇到 yield 语句就完成一个元素的推导并返回,再次执行 next() 时从上次返回的 yield 语句处继续向后执行:
def func(): def func(): print 'one' print 'one' yield 1 yield 1 print 'two' print 'two' yield 2 yield 2 print 'three' print 'three' yield 3 yield 3test = func() test = func()test.next() test.next()test.next() test.next()for item in test: for item in test: print item item# one # one# two # two# three # three# 3 # 此时并没有打印生成器的最后一个元素值
生成器函数应用示例
用生成器产生斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到:
直接打印元素:
def func(max): before = 0 after = 1 while after < max: print before before, after = after, before + after func(10)# 0# 1# 1# 2# 3# 5
使用列表保存结果:
def func(max): list = [] before = 0 after = 1 while after < max: list.append(before) before, after = after, before + after return list my_list = func(10)print my_list# [0, 1, 1, 2, 3, 5]
使用生成器:
def func(max): before = 0 after = 1 while after < max: yield before before, after = after, before + after test = func(10)print testfor item in test: print item## 0# 1# 1# 2# 3# 5