Python:生成器

大数据学习路线图

【版权声明】博客内容由厦门大学数据库实验室拥有版权,未经允许,请勿转载!版权所有,侵权必究!
[返回Python教程首页]

生成器

当列表元素很多,而列表后续元素可以通过某种算法推导出来,我们就不用存储完整的列表,从而节省大量的空间。生成器可以利用for循环访问,也可以利用next()来一次访问元素。
创建生成器的两种方法:
1. 把一个列表生成式的[]改成()
2. 在函数代码中添加yield关键字
第一种是把一个列表生成式的[]改成()。例如:

>> list = [2*x for x in range(3)]   #创建列表List=[0,2,4], range(3)=[0,1,2]
>>> list    #list可以通过for或next()访问
[0, 2, 4]
>>> gene = (2*x for x in range(3))  #创建生成器gene
>>> gene
<generator object <genexpr> at 0x7fcdb6e0c3b8>
>>> next(gene)     #访问生成器第1个元素
0
>>> next(gene)     #访问生成器第2个元素
2
>>> next(gene)     #访问生成器第3个元素
4
>>> next(gene)     #上一步已经遍历完成,再次调用next()会报StopIteration的错误
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

第二种是在函数代码中添加yield关键字。在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回yield的值。并在下一次执行 next()方法时从当前位置继续运行。例如:

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return 'done'

f = fib(6)          #f是生成器,斐波拉契数列的前6项
print(next(f))      #输出斐波拉契数列的第1项
print(next(f))      #输出斐波拉契数列的第2项
print(next(f))      #输出斐波拉契数列的第3项
print(next(f))      #输出斐波拉契数列的第4项
print(next(f))      #输出斐波拉契数列的第5项
print(next(f))      #输出斐波拉契数列的第6项
print(next(f))      #生成器f只有6个元素,继续调用next()会提示错误StopIteration,并返回fib函数的返回值"done"

输出结果为:

1
1
2
3
5
8
Traceback (most recent call last):
  File "gene.py", line 16, in <module>
    print(next(f))
StopIteration: done

总结

通过for循环访问:集合类数据类型(列表等)、生成器和迭代器。
通过next()访问:迭代器和生成器