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

    生成器generator 在Python中3,这种一边循环一边计算的机制,称为生成器,生成器保存的是算法,能节省大量的空间.生成器只记录当前位置,只有一个next()方法。

    通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

    所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器(Generator)。

    简单生成器:

    要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:

    L = [x * x for x in range(10)]
    G = (x * x for x in range(10))
    print(L)
    >>>[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    print(G)
    >>><generator object <genexpr> at 0x0000027BFE39C4F8>

    创建L和G的区别仅在于最外层的[]和(),L是一个list,而G是一个generator。

    我们可以直接打印出list的每一个元素,但我们怎么打印出generator的每一个元素呢?

    可以使用next(G),计算出下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。正确的方法是使用for循环,因为generator也是可迭代对象. 

    带yield 语句的生成器

    下面代码可以从第一个元素开始,通过相应的算法推算出后续任意的元素,这种逻辑其实非常类似generator。

    def fib(max):
        n, a, b = 0, 0, 1
        while n < max:
            yield b
            a, b = b, a + b
            n = n + 1
    G=fib(6)
    print(G)
    

    这里,最难理解的就是generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。 

    加强的生成器

    一些加强特性加入到生成器中,所以除了 next()来获得下个生成的值,用户可以将值回送给生成器[send()],在生成器中抛出异常,以及要求生成器退出[close()]。

    def gen(x):
        count = x
        while True:
            val = (yield count)
            if val is not None:
                count = val
            else:
                count += 1
    G = gen(5)
    print (next(G))
    >>>5
    print (next(G))
    >>>6
    print (next(G))
    >>>7
    print('====================')
    print (G.send(9))#发送数字9给生成器
    >>>9
    print (next(G))
    >>>10
    print (next(G))
    >>>11
    G.close()
    

     通过send()可以把数据9发送给生成器,当生成器close后,就不能再对生成器进行操作了。 

  • 相关阅读:
    java中继承和多态的理解
    汽车租赁系统
    s2第六章继承和多态
    第三章泛型集合ArrayList 和Hashtable
    第二章项目总结
    s2第二章深入c#类型
    .NET平台
    航班查询系统
    java初始重点语法
    JDBC
  • 原文地址:https://www.cnblogs.com/paulwinflo/p/12259647.html
Copyright © 2011-2022 走看看