Python中的生成器

64 阅读2分钟

生成器的优点

生成器采用了惰性求值策略,对于没有用到的部分,在内存里面只是一个表达式(算法),并不会真正的去做计算,只有在我们需要的时候才生成和返回下一个值。

当我们遇到需要处理不定长度的列表操作或者想要节省内存空间,惰性求值可以自动的最小化我们的计算量,节约资源。

惰性求值策略涉及到了一个编程设计思想,即在有限的内存表达无限的概念。

生成器的应用

  1. 处理数据流或大文件:在读写文件时,使用生成器,它本身不会把整个文件加载到我们的内存里面,而是按需的读取。
  2. python内置的惰性迭代器
    • range()
    • map()
    • filter()

生成器的两种定义方式

  1. 和列表生成式很像,使用() 而不是 []
generator_ = (x**2 for x in range(10))

这个表达式会创建一个生成器对象g,它可以产生0到9之间的数的平方,但是,它不会立即计算出所有的值,而是在每次调用generator_的next()方法时才会计算出下一个值。

生成器表达式中使用的变量x,会在一个单独的作用域中求值,这个作用域和生成器对象generator_。

但是,生成器表达式中最左边的for子句中的in表达式,会立即在当前作用域中求值。

  1. 在函数中,使用yield返回下一个值
def divby2(n):
    num = 0
    while num < n:
        yield num/2
        num += 1

在每次调用next()时执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。

获取生成器的值

  1. 使用 next()函数
  2. 使用 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)