生成器的优点
生成器采用了惰性求值策略,对于没有用到的部分,在内存里面只是一个表达式(算法),并不会真正的去做计算,只有在我们需要的时候才生成和返回下一个值。
当我们遇到需要处理不定长度的列表操作或者想要节省内存空间,惰性求值可以自动的最小化我们的计算量,节约资源。
惰性求值策略涉及到了一个编程设计思想,即在有限的内存表达无限的概念。
生成器的应用
- 处理数据流或大文件:在读写文件时,使用生成器,它本身不会把整个文件加载到我们的内存里面,而是按需的读取。
- python内置的惰性迭代器
range()
map()
filter()
生成器的两种定义方式
- 和列表生成式很像,使用
()
而不是[]
generator_ = (x**2 for x in range(10))
这个表达式会创建一个生成器对象g,它可以产生0到9之间的数的平方,但是,它不会立即计算出所有的值,而是在每次调用generator_的next()方法时才会计算出下一个值。
生成器表达式中使用的变量x
,会在一个单独的作用域中求值,这个作用域和生成器对象generator_。
但是,生成器表达式中最左边的for子句中的in表达式,会立即在当前作用域中求值。
- 在函数中,使用yield返回下一个值
def divby2(n):
num = 0
while num < n:
yield num/2
num += 1
在每次调用next()时执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
获取生成器的值
- 使用
next()
函数 - 使用 for 循环做迭代
用生成器实现一个斐波那契数列
斐波那契数列是每个值等于前两项之和。即f(n) = f(n-1) + f(n-2).
定义fibo_generator函数,产生斐波那契数列的前n项。
def fibo_generator(n):
# 最前面两项的值
a = 0
b = 1
for i in range(n):
yield a
a, b = b, a+b
用for循环或next()函数来遍历这个生成器对象,得到斐波那契数列的值
gen = fib(10)
for num in gen:
print(num)