• python学习笔记 day14 生成器进阶(二)


    移动平均值

    假如我们有一个需求,需要计算输入数的平均值,以往都是输入的数字是固定的直接求和除以个数即可,现在输入一个数字,平均值就得更新一次,应该怎么处理呢?

    我们需要用到生成器,而且需要用到之前提到的send()方法需要传值,然后yield返回 avg:

    def generator():
        sum=0
        count=0
        avg=0
        while True:
            num=yield avg
            sum+=num
            count+=1
            avg=sum/count
    g=generator()
    g.__next__()
    print(g.send(10))
    print(g.send(20))
    print(g.send(30))
    print(g.send(40))
    print(g.send(50))
    print(g.send(60))

    说一下代码的执行流程:

    首先generator()函数是一个生成器函数,该函数被调用返回一个生成器给g,首先g.__next__()会先执行到yield avg停止,但是g.__next__()并没有接受返回值,然后执行g.send(10)就是从第一个yield的位置开始,把10赋值给num,然后往下执行,计算均值,然后执行下一个循环,第一句遇到yield avg  把sum=10,count=1计算的返回值avg=10 传给了g.send(10)这里,print()打印出来,后续就重复进行上述传num ,计算avg,yield停止并把avg传给g.send()等

    其实我们还可以使调用函数的人更简洁,就是只需要调用g.send(10)传值就可以直接计算每次生成的均值,也就是没有最开始那个g.__next__()函数初试刺激一下生成器函数内部了:

    def init(f):
        def inner(*args,**kwargs):
            g=f(*args,**kwargs)
            g.__next__()
            return g
        return inner
    
    @init
    def generator():
        sum=0
        count=0
        avg=0
        while True:
            num=yield avg
            sum+=num
            count+=1
            avg=sum/count
    
    g=generator()
    print(g.send(10))
    print(g.send(20))
    print(g.send(30))
    print(g.send(40))
    print(g.send(50))

    运行结果:

    装饰器的功能就是替代了g.__next__()这一句而已,使得调用者看似不需要写这一句,直接g.send(10)就可以得到每次更新的均值啦!!

    还需要说一点,就是装饰器内部,inner()这个闭包函数里面的代码就是跟外部怎么使用func函数是一样的,该返回值就返回值,该返回一个生成器就返回一个生成器~

    yield from

    如果我们需要挨个打印某个可迭代对象的值,使用生成器,可以这样操作:

    def generator():
        a='jkldf;df'
        b='sjkdlfkld'
        for i in a:
            yield i
        for i in b:
            yield i
    g=generator()
    for i in g:
        print(i)

    运行结果:

    其实还可以更简单:

    def generator():
        a='jdskfkldfk'
        b='sjkdfl'
        yield from a
        yield from b
    g=generator()
    for i in g:
        print(i)
    talk is cheap,show me the code
  • 相关阅读:
    第二阶段个人总结八
    第二阶段个人总结七
    第二阶段个人总结六
    第二阶段个人总结五
    电梯演说模板练习
    对敏捷开发的理解
    团队的不同形式
    认识JQuery的三天--看视频得到的一些小知识点
    结对编码
    结对互评
  • 原文地址:https://www.cnblogs.com/xuanxuanlove/p/9589017.html
Copyright © 2020-2023  润新知