zoukankan      html  css  js  c++  java
  • 一段关于生成器代码的解读

       首先感谢:http://www.cnblogs.com/zhuhaofeng/articles/9469897.html,这篇博客的作者,把这段代码的过程一步步进行的分解,希望可以帮助大家更好的理解这段代码。
    从而,更好的理解生成器。要理解这段代码,需要先了解生成器的两个特点:
    1.惰性机制
    2.生成器,在被调用之前,只是代表着一段没有被执行过的代码
    ---------------------------------------下面是最开始的代码--------------------------------------------------------
    1.0
    有一个有意思的python面试题,是下面的这个样子

    def add(a,b): #普通求和函数
    return a + b
    def test(): #生成器函数
    for r in range(4):
    yield r
    g=test()
    for n in [2,10]:
    g=(add(n,i) for i in g)
    print(list(g))
    ---------------------------------------下面是第一步分解-------------------------------------------------------
    1.1:代码块注释如下(还是上面的内容,只是注释加多了)
    def add(a,b):                     #普通求和函数
    return a + b
    def test(): #生成器函数
    for r in range(4):
    yield r
    g=test() #获取生成器对象,后面的操作都指向这个对象,这和直接执行fun()函数销效果是不一样的
    for n in [2,10]: #因为前面已经定义了生成器g,这个for循环的代码块等于是重新定义了变量g,
    g=(add(n,i) for i in g) #重新定义的这个变量g也是一个生成器,使用推导式定义的生成器
    print(list(g)) #list自带for方法,所以list(g)会一次性把上面列表生成器的值拿完
    ---------------------------------------下面是第二步分解---------------------------------------------------------
    1.2:代码简化(对上面的代码做了简化,但是都是等效的,主要是对for循环做了简化)
    def add(a,b):            #普通求和函数
    return a + b
    def test(): #生成器函数
    for r in range(4):
    yield r
    g=test()
    n=2 #这一行到下一步后,就没有了,我开始没理解。为什么就可以省略了?答案是当n=2时,只是生成了一个生成器,而并没有执行括号里面的代码,因为这时,没有人去调用
    #这个生成器,所以这时的g只是代表着一段代码:(add(n,i) for i in g)。
    g=(add(n,i) for i in g)
    n=10
    g=(add(n,i) for i in g)
    print(list(g))
    ---------------------------------------下面是第三步分解-----------------------------------------------------------
    1.3:代码简化(对上面的代码做了简化,但是都是等效的,主要是对n重新赋值的过程做了简化)
    def add(a,b):            
    return a + b
    def test():
    for r in range(4):
    yield r
    g=test()
    n=10 #和上面的代码做比较,n重新赋值了两次,第二次已经把一次的赋值覆盖掉了,但是g因为前面做过定义,需要带入。
    #因为n=2时,没有执行括号里面的代码,所以,走到了n=10。但是,这时括号里面的代码还是没有执行,这个时候的g也不过是
    #一段代码:(add(n,i) for i in g)。而且,这时的n已经被重新赋值了,n=10.已经在内存中存在了。
    g=(add(n,i) for i in (add(n,i) for i in g))#这里最外层括号里的g,是n=2时的生成器,第二步已经说过,那时的g只不过是一段代码,所以直接带过来就好了。
    print(list(g))
    ---------------------------------------下面是第四步分解-----------------------------------------------------------
    1.4:代码简化(对上面的代码做了简化,但是都是等效的,带入数字10)

    def add(a,b):

    return a + b
    def test():             
    for r in range(4):
    yield r
    g=test()

    g=(add(10,i) for i in (add(10,i) for i in g))
    print(list(g))#走到这里时,因为list中有__next__(),所以开始跟生成器要值了,生成器开始循环起来。
    #因为for循环自带__next__方法,所以for循环作用于生成器的时候也是一次性遍历完的,并不需要单独的在一个一个执行next
    #分别带入i值0,1,2,3,可以生成g的一个生成器结果,再通过list(g)一次性拿完
    -----------------------------------------------------------------------------------------------
  • 相关阅读:
    不过的小东东
    基础练习 特殊回文数
    基础练习 特殊回文数
    基础练习 特殊回文数
    web.input()与web.data()函数比较
    web.input()与web.data()函数比较
    web.input()与web.data()函数比较
    MFC 服务管理
    Fedora Documentation
    Centos7 安装vnc
  • 原文地址:https://www.cnblogs.com/asia-yang/p/10110983.html
Copyright © 2011-2022 走看看