• python之路_生成器进阶及相关表达式


    一、生成器中的send用法

      send可以把一个值作为信号量传递到生成器函数中,然后和__next__方法一样获取生成器中的值;在生成器执行伊始,只能先使用__next__;二者都是终于yield,而send需要始于一个未被返还的yield处,否则传递的数值将无法被接收。

    1、求重复累加平均实例

    def average():
        count=0
        toatal=0
        average=0
        while True:
            value=yield average
            toatal+=value
            count+=1
            average=toatal/count
    g=average()
    print(g.__next__())                           #激活了生成器,返回yield后面的average,为0
    print(g.send(10))                             #把10传递给yield前的value,继续执行后面的代码,终于yield后面的average,返回10
    print(g.send(20))                             #把20传递给yield前的value,继续执行后面的代码,终于yield后面的average,返回15
    print(g.send(30))                             #..........
    print(g.send(40))
    print(g.send(50))

    2、用send传值失败实例

    def func():
        print(1)
        yield 2
        print(3)
        value = yield 4
        print(5)
        yield value
    
    g = func()
    print(g.__next__())                          #打印出1和返回2,然后在第一个yield处停止等待
    print(g.send(88))                            #由于第一个yield处没有未被返回的值,故send传值失败,打印出3和返回4,在第二个yield处停止等待
    print(g.__next__())                          #value无值传入,打印出5后在第3个yield处返回none

    3、用next激活生成器计算累加平均值

    def init(func):                              #在调用被装饰生成器函数的时候首先用next激活生成器
        def inner(*args,**kwargs):
            g=func(*args,**kwargs)
            next(g)
            return g
        return inner
    @init
    def average():
        mount=0
        total=0
        average=0
        while True:
            value=yield average
            total+=value
            average=total/mount
    g_avg=average()
                                                # next(g_avg)   在装饰器中执行了next方法
    print(g_avg.send(10))
    print(g_avg.send(20))
    print(g_avg.send(30))

    二、列表表达式和生成器表达式

    1、列表表达式

      简化代码,返回的必须是一个列表

    #普通代码
    result=[]
    for i in [1,2,3]
        result.append[i*i]
    print(result)
    
    #列表表达式
    print([i*i for i in [1,2,3]])

    (1)30内能被3整除的数的实例

    print([i for i in range(1,31) if i%3==0])

    (2)找到嵌套列表中有两个‘e’的名字

    names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'], ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
    print([for list in names for name in list if name.count('e')==2])

    2、生成器表达式

      把列表解析的[]换成()得到的就是生成器表达式;列表解析与生成器表达式都是一种便利的编程方式,只不过生成器表达式更节省内存

    laomuji=('鸡蛋%s' %i for i in range(10))        #生成器表达式
    print(laomuji)                                 #返回生成器地址<generator object <genexpr> at 0x000001E17AF23BA0>
    print(next(laomuji))                           #输出结果为:鸡蛋0
    print(laomuji.__next__())                      #输出结果为:鸡蛋1
    print(next(laomuji))                           #输出结果为:鸡蛋2
                                                   #next(laomuji)等价于laomuji.__next__()

    3、字典推导式

    #将字典键与值对调
    mcase = {'a': 10, 'b': 34}
    print({mcase[k]:k for k in mcase})

    4、集合推导式

      自带去重功能,将列表解析式的[]换成{}得到集合推导式

    print({i*i for i in [1,-1,2]})    #结果为{1,4}

     三、生成器表达式面试题

      生成器表达式得到是一个生成器 ,生成器只有在取值的时候才能返出值。如下实例得到生成器g的存储地址,并不会如愿得到(1,4,9,16)

    g=(i**2 for i in [1,2,3,4])
    print(g)

      面试实例:

  • 相关阅读:
    Soap 教程
    MAC mysql install
    PHP date
    MAC 终端terminal颜色
    MAC 终端颜色设置
    MAC brew软件安装
    PHP iconv函数
    Java----前端验证之验证码额实现
    Java---Ajax在Struts2框架的应用实例
    Java基础—标识符及命名规范
  • 原文地址:https://www.cnblogs.com/seven-007/p/7479430.html
Copyright © 2020-2023  润新知