• day14 生成函数的进阶


    一、上节回顾:

    1、可迭代对象:惰性运算          拥有__iter__方法

    2、迭代器:                              拥有__iter__和__next__方法

    3、生成器:惰性运算,开发者自定义   本质:迭代器 所以拥有__iter__和__next__方法

         惰性运算:不取值就不计算  且每一个值只能被取一次,取完为止

         生成器的优点:延迟计算,一次返回一个结果,也就是说,它不会一次生成所有的结果,这对于大数据处理非常有用

    生成器------迭代器:节省内存

    1)生成器函数:

       带有yield 关键字

       执行函数之后的返回值是生成器,函数内的代码并不会真正执行

       想让生成器吐出数据,需要使用next 方法,send, for循环

    二、新内容

    1、生成器的调用例子 取用:cloth

    def cloth():
        for i in range(100):
            yield "衣服%s"%i
    g=cloth()
    # 方法一
    # for i in g:
    #     print(i)
    # 方法二
    for i in range(100):
        print(g.__next__())
    cloth

    2、监听文件末尾追加的例子

    调用生成器并不执行,当取用的时候才会执行def下面的内容(Windows系统的时候才可以使用)

    def tail():
        f=open("你好.bak","r",encoding="utf-8")
        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.strip())
    生成器(监听文件)

    3、send  和next 的范围是一样的

         (1)从哪一个yield开始接着执行,就把一个值传给了那个yield

        (2)send 不能用在第一个触发生成器,触发生成器第一个必须是__next__()

         (3)生成器函数中有多少个yield就必须有多少个next+send

    def func():
        print("*"*10)
        a=yield 5
        print(a)
        yield  10
    g=func()
    num=g.__next__()
    print(num)
    num2=g.send("alex")
    print(num2)
    # **********
    # 5
    # alex
    # 10
    send 例子
    def averager():
        total=0.0
        count=0
        average=None
        while True:
            term=yield  average
            total+=term
            count+=1
            average=total/count
    g_avg=averager()
    g_avg.__next__()
    print(g_avg.send(10))
    print(g_avg.send(20))
    print(g_avg.send(30))
    # 10.0
    # 15.0
    # 20.0
    利用 send(银行七日化利息)

    4、补充:python3 之后有的这个功能:yield from a

    def func():
        a="AB"
        b="CD"
        yield from a
        #for i in a:yield i
        yield from b
        #for i in b:yield i
    g_func=func()
    for i in g_func:
        print(i)
    yield from 的使用

    5、触发执行的方式

    (1)生成器.__next__()

     (2)生成器.send()        

          send(None)==__next__().  

          send在next的基础上传一个值到生成器函数的内部

          send 操作不能用在生成器使用的第一次

          以上两个执行几次拿几个数据,可能会遇到取完报错

    (3)for循环   每次取一个,取完为止。for循环不会报错

    6、总结:

        生成器函数:生成一个生成器的函数

        生成器的本质:参数迭代器

        生成器函数的特点:(1)带有yield 关键字 (2)且调用之后,函数内的代码不执行

     触发执行的方式:(1)next  (2)send  (3)for 循环

    三、各种推导式

     1、列表推导式:

    y=[1,2,3,4,5,6,7]
    # 方法一
    # x=[]
    # for i in y:
    #     x.append(i**2)
    # print(x)
    # 方法二
    x=[i**2 for i in y]
    print(x)
    # [1, 4, 9, 16, 25, 36, 49]
    列表推导式1
    # x=[]
    # for i in range(100):
    #     x.append(i/2)
    # print(x)
    x=[i/2 for i in range(100)]
    print(x)
    列表推导式2

    2、生成器表达式 (生成器表达式+for循环节省内存 推荐使用)

    #列表推导式
    y=[1,2,3,4,5,6]
    x=[i**2 for i in y]  #[  ]
    print(x)
    #生成器表达式
    y=[1,2,3,4,5,6]
    g=(i**2 for i in y)  #(  )
    print(g)
    for i in g:
        print(i)
    列表推导式和生成器表达式
    l=["鸡蛋%s"%i for i in range(10)]
    print(l)
    lmuji=("鸡蛋%s"%i for i in range(10))
    for egg in lmuji :
        print(egg)
    鸡蛋和母鸡的理论

     3、补充:

    并不是所有的都可以转换

    g.__next__()==next(g )
    g.__iter__()==inter(g)

    4、30以内能被3整除的数的平方 列表推导式的例子

    # 30以内能被3整除的数的平方
    # x=[i**2 for i in range(30) if i%3==0]
    # print(x)
    def square(x):
        return  x**2
    x=[square(i) for i in range(30) if i%3==0]
    print(x)
    30以内能被3整除的数的平方

    5、字典推导式

    dic={"a":10,"b":34}
    dic_fre={dic[k]:k for k in dic}
    print(dic_fre)
    #{10: 'a', 34: 'b'}   key value 对换
    key value 对换
    mcase={"a":10,"b":34,"A":7,"Z":3}
    mcase_frequency={k.lower():mcase.get(k.lower(),0)+mcase.get(k.upper(),0)for k in mcase}
    print(mcase_frequency)
    #{'a': 17, 'b': 34, 'z': 3}
    字典中大小写相加

    6、集合的推导式 去重

    squared={x**2 for x in [1,-1,2]}
    print(squared)
    #set([1,4])
    集合的去重

    面试题:

  • 相关阅读:
    mysql添加外键的4种方式
    时序分析(1):时序约束原理(旧版、可能有错)
    SignalTap II——基本使用和高级技巧
    Testbench编写技巧
    异步复位同步释放
    协议——SCCB与IIC的区别
    协议——IIC
    Modelsim——显示状态机名称的方法
    亚稳态
    计数器(2):递增再递减,不断循环
  • 原文地址:https://www.cnblogs.com/number1994/p/7979141.html
Copyright © 2020-2023  润新知