**生成器 (generator)** 在 Python 中一边循环一边计算的方式称为生成器 ( generator )。 当我们需要使用无穷无尽的数据的时候,由于电脑机器的内存是有限的,不可能一次性存储那么多的数据,我们就可以根据某种规律计算出下一个数据的值,我们只需保存算法,这样就节省大量的空间,而不需要保存真实的海量数据,再在循环中不断推算下一个数据值的思想就诞生了生成器 ( generator )。 **生成器的创建常用方法** 方法一:把一个列表生成式的 [ ] 改成 ( ),就创建了一个生成器 ( generator )。 ~~~ >>> _list = [ i for i in range(3)] >>> _list [0, 1, 2] >>> gene = (i for i in range(3)) >>> gene <generator object <genexpr> at 0x7f495742a6d0> ~~~ 使用列表生成式生成的列表我们可以直接打印出列表中的每一个元素,但是生成的生成器对象我们却只得到了一个内存地址,那如何获取生成器对象中的元素呢? 通过 next() 方法打印生成器中的元素,直到最后抛出 StopIteration 错误表示无法继续返回下一个值了。 ~~~ >>> next(gene) 0 >>> next(gene) 1 >>> next(gene) 2 >>> next(gene) #抛出 StopIteration 错误 Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration ~~~ 当然我们也可以使用 for 循环打印生成器中的元素 ~~~ #!/usr/bin/env python3 # -*- coding:utf-8 -*- gene = (i for i in range(3)) for i in gene: print(i) ~~~ 方法二:在函数定义中使用了 yield 关键字,那么这个函数就不再是一个普通函数,而是一个生成器 ( generator )。 生成器 ( generator ) 和普通函数的执行流程不一样。函数是顺序执行,遇到 return 语句或者最后一行函数语句就返回。而生成器 ( generator ) 的函数,在每次调用 next() 的时候执行,遇到 yield 语句返回,再次执行时从上次返回的 yield 语句处继续执行 , 更简单点理解生成器就是一个迭代器。 **实例说明** ~~~ >>>def info(): ... print('Python') ... yield 1 ... print('PHP') ... yield 2 ... print('Java') ... yield 3 ... ~~~ 调用时,首先要生成一个生成器 ( generator ) 对象,然后用 next() 函数不断获得下一个返回值: ~~~ >>> g = info() >>> next(g) #第一次调用 Python 1 >>> next(g) #第二次调用 PHP 2 >>> next(g) #第三次调用 Java 3 >>> next(g) #抛出 StopIteration 错误 Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration ~~~ 可以看出, info() 已经不是一个普通函数而是生成器,在调用过程中遇到 yield 就中断,下次又在中断出继续执行。执行 3 次 yield 后,已经没有 yield 可以执行了,所以,第 4 次调用 next(g) 就抛出 StopIteration 的错误。 实例使用 yield 实现斐波那契数列 ~~~ #!/usr/bin/env python3 # -*- coding:utf-8 -*- def fibonacci(n): # 斐波那契生成器函数 a, b, num = 0, 1, 0 while True: if (num > n): return yield a a, b = b, a + b num += 1 g = fibonacci(3) # g是一个由斐波那契生成器函数返回迭代器 while True: try: print (next(g), end=",") except StopIteration: break ~~~ 执行结果 ~~~ 0,1,1,2, ~~~ 当然在实际开发中我们很少使用 while 去循环迭代器,因为使用 for 进行迭代更方便。