• day14生成器


    生成器

    我自己想写个可迭代的,——生成器
    生成器的本质就是迭代器
    因此生成器的所有好处都和迭代器一样
    但是生成器是我们自己写的python代码
    生成器的实现有两种方式:
    1.生成器函数
    2.生成器表达式

    复制代码
    def func():
        return ['衣服1','衣服2000000']
    
    ret = func()
    print(ret)
    
    def g_func():
        yield 1
    
    g = g_func()
    print(g)  # <generator object g_func at 0x00000000006AAFC0>
    generator 生成器  ---> 迭代器
    print('__iter__' in dir(g))  # True
    print('__next__' in dir(g))  # True
    print(g.__next__())  # 1
    复制代码

    生成器函数和普通函数之间的区别
    生成器函数中含有yield关键字
    生成器函数调用的时候不会立即执行,而是返回一个生成器

    复制代码
    def g_func():
        print('aaaa')
        yield 1
        print('bbbb')
        yield 2
    
    g = g_func()
    for i in g:
        print(i)
    # print(g.__next__())
    # print(g.__next__())
    
    def cloth():
        for i in range(1000000):
            yield '衣服%s'%i
    
    g_cloth = cloth()
    print(g_cloth.__next__())
    print(g_cloth.__next__())
    复制代码

     监听文件末尾追加的例子

    复制代码
    def tail():
        f = open('文件',encoding='utf-8')
      # print('__iter__' in dir(f))  # True
      # print('__next__' in dir(f))  # True
        f.seek(0,2)
        while True:
            line = f.readline()
            if line:
                yield line
            import time
            time.sleep(0.1)
    g = tail()
    for i in g:
        print(i)
    复制代码

    send的用法

    复制代码
    def func():
        print('*'*10)
        a = yield 5
        print('a :',a)
        yield 10
    
    g = func()
    num = g.__next__()
    print(num)
    num2 = g.send('alex')  # 相当于next,但是会传值给yield前的变量
    print(num2)
    复制代码

    send:从哪一个yield开始接着执行,就把一个值传给了哪个yield
    send不能用在第一个触发生成器
    生成器函数中有多少个yield就必须有多少个next+send

    计算移动平均值

    复制代码
    def init(func):  # 生成器的预激装饰器
        def inner(*args,**kwargs):
            g = func(*args,**kwargs)
            g.__next__()
            return g
        return inner
    
    @init
    def averager():
        total = 0.0
        count = 0
        average = None
        while True:
            term = yield average
            total += term
            count += 1
            average = total/count
    
    
    g_avg = averager()
    # next(g_avg)  # g_avg.__next__()
    print(g_avg.send(10))
    print(g_avg.send(30))
    print(g_avg.send(5))
    复制代码

    yield from

    复制代码
    def func():
        a = 'AB'
        b = 'CD'
        yield from a  # 接收一个可迭代对象,相当于下面的for,python3特有
        # for i in a:
        #     yield i
        yield from b
        # for j in b:
        #     yield j
    g = func()
    for i in g:
        print(i)
    复制代码

    生成器函数:生成一个生成器的函数
    生成器的本质才是迭代器
    生成器函数的特点:
    带有yield关键字,且调用之后,函数内的代码不执行
    触发执行的方式:
    next
    send send(None) == __next__()
    for循环

    生成器表达式

    复制代码
    y = [1,2,3,4,5,6,7,8]
    g = (i**2 for i in y )
    print(g)  # <generator object <genexpr> at 0x00000000006AAFC0>
    print(list(g))  # [1, 4, 9, 16, 25, 36, 49, 64]
    # for i in g:
    #     print(i)
    
    l = ['鸡蛋%s'%i for i in range(10)]
    print(l)
    laomuji = ('鸡蛋%s'%i for i in range(10))
    for egg in laomuji:
        print(egg)
    复制代码

    面试题

    复制代码
    def demo():
        for i in range(4):
            yield i
    
    g=demo()
    
    g1=(i for i in g)
    g2=(i for i in g1)
    
    print(list(g1))  # [0, 1, 2, 3]
    print(list(g2))  # []
    复制代码
    复制代码
    def add(n,i):
        return n+i
    
    def test():
        for i in range(4):
            yield i
    
    g=test()
    for n in [1,10]:
        g=(add(n,i) for i in g)
    # n = 1
    # g=(add(n,i) for i in test())
    # n = 10
    # g=(add(10,i) for i in (add(10,i) for i in test()))
    
    print(list(g))  # [20, 21, 22, 23]
  • 相关阅读:
    魔兽世界服务器Trinitycore分析二:auth server的main函数
    白话经典算法系列之七 堆与堆排序
    Opencv学习笔记(六)SURF学习笔记
    sprintf,你知道多少?
    色相环上面的颜色和相邻颜色的关系是什么
    视达配色教程10 绿色的意向是什么
    网页设计实战3 ufo类型的科技网页如何实现
    如何使用echo.js实现图片的懒加载(整理)
    网页设计实战1 如何实现纸叠登录效果
    人为什么要好好努力学习工作
  • 原文地址:https://www.cnblogs.com/QQ279366/p/7804249.html
Copyright © 2020-2023  润新知