zoukankan      html  css  js  c++  java
  • python 生成器 generator

    一、生成器定义

    通过列表生成表达式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。

    1 >>> l = [x * x for x in range(10)]
    2 >>> l
    3 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    4 >>> g = (x * x for x in range(10))
    5 >>> g
    6 <generator object <genexpr> at 0x1013e0780>

    二、表达式生成器

    创建l和g的区别仅在于最外层的[]和(),l是一个list,而g是一个generator。可以直接打印出l的每一个元素,打印出g的每一个元素需要使用next()函数。

     1 >>> g = (x * x for x in range(10))
     2 >>> g
     3 <generator object <genexpr> at 0x1013e0780>
     4 >>> next(g)
     5 0
     6 >>> next(g)
     7 1
     8 >>> next(g)
     9 4
    10 >>> next(g)
    11 9
    12 >>> next(g)
    13 16
    14 >>> next(g)
    15 25
    16 >>> next(g)
    17 36
    18 >>> next(g)
    19 49
    20 >>> next(g)
    21 64
    22 >>> next(g)
    23 81
    24 >>> next(g)
    25 Traceback (most recent call last):
    26   File "<stdin>", line 1, in <module>
    27 StopIteration

    generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。

     1 >>> g = (x * x for x in range(10))
     2 >>> for n in g:
     3 ...     print(n)
     4 ... 
     5 0
     6 1
     7 4
     8 9
     9 16
    10 25
    11 36
    12 49
    13 64
    14 81

    首先generator是可迭代对象,所以可以使用for in循环遍历。该遍历的本质是for in循环内部调用next()函数获取每一个元素,并且捕获StopIteration异常,结束遍历。

    三、函数生成器

    斐波拉契数列用列表生成式写不出来,但是,用函数把它打印出来却很容易。

     1 >>> def fib(max):
     2 ...     n, a, b = 0, 0, 1
     3 ...     while n < max:
     4 ...         yield b
     5 ...         a, b = b, a + b
     6 ...         n += 1
     7 ...     raise StopIteration('done')
     8 ... 
     9 >>> fib(6)
    10 <generator object fib at 0x1013e0780>
    11 >>> for i in fib(6):
    12 ...     print(i)
    13 ... 
    14 1
    15 1
    16 2
    17 3
    18 5
    19 8
    20 >>> g = fib(6)
    21 >>> while True:
    22 ...     try:
    23 ...         next(g)
    24 ...     except StopIteration as e:
    25 ...         print(e.value)
    26 ...         break
    27 ... 
    28 1
    29 1
    30 2
    31 3
    32 5
    33 8
    34 done
  • 相关阅读:
    java反射——字段
    java反射——方法
    java反射——构造方法
    代构建高可用分布式系统的利器——Netty
    JavaEE复习计划
    Java基础复习计划(三)
    Java基础复习计划(二)
    Java基础复习计划
    关于内网穿透的相关内容
    Docker化你的应用
  • 原文地址:https://www.cnblogs.com/gundan/p/8047495.html
Copyright © 2011-2022 走看看