zoukankan      html  css  js  c++  java
  • 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]
  • 相关阅读:
    匿名函数与内置函数(python3入门)
    迭代器和生成器(python3入门)
    python中文件操作方法(python3入门)
    python所有数据类型及操作(python3入门)
    Python语法命令学习-Day3(作业练习)
    Python语法命令学习-Day3(零基础)
    构建之法阅读笔记01
    学习进度条
    软件工程个人作业01
    阅读计划
  • 原文地址:https://www.cnblogs.com/QQ279366/p/7804249.html
Copyright © 2011-2022 走看看