• 生成器 生成器函数 各种推导式 生成器表达式


    生成器
    本质就是迭代器.
    一个一个的创建对象
    创建生成器的方式:
    1. 生成器函数
    2. 通过生成器表达式来获取生成器
    3. 类型转换(看不到)

    def func():
        print("我叫周润发")
        return "林志玲"               # return在函数中表示返回的意思
    
    
    ret = func()
    print("返回值是", ret)
    
    函数中包含了yield, 此函数就是生成器函数
    大坑: 生成器函数运行之后. 产生一个生成器. 而不是运行函数
    def func():
        print("我叫周润发")
        yield "林志玲"          # yield表示返回. 不会终止函数的执行
        print("宝宝干嘛去了??")
        yield "宝宝回来了"
        print("宝宝你在干嘛?")
        # yield "没了"
    
    ret = func() # 执行函数, 此时没有运行函数.
    # # 此时我们拿到的是生成器
    # print("返回值是", ret) # <generator生成器 object func at 0x0000000009E573B8>
    
    # 执行到下一个yield
    print(ret.__next__()) # 第一次执行__next__此时函数才开始执行
    print(ret.__next__()) # 执行到下一个yield
    print(ret.__next__()) # StopIteration
    
    买衣服, JACK JONES  10000
    def buy():
        lst = []
        for i in range(10000):
            lst.append("衣服%s" % i)
        return lst
    
    lst = buy()
    print(lst)
    
    
    def buy():
        for i in range(10000):
            yield "衣服%s" % i
    
    gen = buy() # 生成器或者迭代器的好处: 节省内存
    # print(gen.__next__())
    # print(gen.__next__())
    # print(gen.__next__())
    
    # for yifu in gen: 迭代器. __next__()
    #     print(yifu)
    
    lst = list(gen) # 内部使用的是for循环  -> __next__()
    print(lst)
    
    
    send() -> __next__()
    send()可以给上一个yield位置传值
    
    
    def func():
        print("韭菜盒子")
        a = yield "韭菜鸡蛋"
        print("a", a)
        b = yield "韭菜西红柿"
        print("b", b)
        c = yield "火烧"
        print("c", c)
    
    gen = func()
    
    print(gen.__next__()) # 第一个位置用send没有任何意义,所以用的是next
    print(gen.send("篮球")) # 给上一个yield位置传值       
    print(gen.send("足球"))
    
    
    def eat():
         print("我吃什么啊")
         a = yield "馒头"
         print("a=",a)
         b = yield "⼤饼"
         print("b=",b)
         c = yield "⾲菜盒⼦"
         print("c=",c)
         yield "GAME OVER"
    
    gen = eat() # 获取⽣成器
    
    ret1 = gen.__next__()
    print(ret1)
    ret2 = gen.send("胡辣汤")
    print(ret2)
    ret3 = gen.send("狗粮")
    print(ret3)
    ret4 = gen.send("猫粮")
    print(ret4)

    生成器函数 (重点)
    生成器函数中包含 yield , 返回数据和return差不多.
    return会立即结束这个函数的执行
    yield 可以分段的执行一个函数

    生成器函数在执行的时候返回生成器. 而不是直接执行此函数

    能向下执行的两个条件:
    __next__(), 执行到下一个yield
    send(), 执行到下一个yield, 给上一个yield位置传值

    所有的生成器都是迭代器都可以直接使用for循环
    都可以使用list()函数来获取到生成器内所有的数据

    生成器中记录的是代码而不是函数的运行
    def func():
      print("我的天哪 ")
      yield "宝宝"
    gen = func() # 创建生成器. 此时运行会把生成器函数中的代码记录在内存
    当执行到__next__(), 运行此空间中的代码, 运行到yield结束.

    生成器函数 

    优点: 节省内存, 生成器本身就是代码. 几乎不占用内存
    特点: 惰性机制, 只能向前. 不能反复

    生成器函数
    def func():
        print(111)
        yield 222
    
    # 惰性机制, 只能向前
    g = func()  # 创建生成器
    g1 = (i for i in g) # 生成器表达式
    g2 = (i for i in g1) # 生成器表达式
    
    #
    print(list(g1))
    print(list(g)) # for -> __next__()
    print(list(g2))

     

    各种推导式

    列表的推导式:[结果 for循环 if判断]

     

    生成列表.类表中装的数据是 1-100之间所有的偶数的平方
    
    
    lst = [i**2 for i in range(1, 101) if i%2 == 0]
    print(lst)
    
    
    筛选出列表中姓张的同学, lst = ["张无忌", "吴奇隆", "张诗诗", "范冰冰", "张翠山"]
    lst = ["张无忌", "吴奇隆", "张诗诗", "范冰冰", "张翠山"]
    lst2 = [name for name in lst if name.startswith("")]
    print(lst2)
    
    
    # 寻找名字中带有两个e的人的名字
    names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven','Joe'],
    ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
    
    
    lst = [name for el in names for name in el if name.count("e") == 2]
    print(lst)

    字典推导式

    语法: { 结果(key:value) for循环 if条件}

    lst = [11,22,33]  # {0:11, 1:22, 2:33}
    
    dic = {i:lst[i] for i in range(len(lst))}
    print(dic)
    
    练习: {"主食": "炒面", "副食": "小拌菜", "":"疙瘩汤"}
    把字典的key和value互换, 生成新字典
    dic =  {"主食": "炒面", "副食": "小拌菜", "":"疙瘩汤"}
    d = { v:k for k, v in dic.items()}
    print(d)

    同理可以推断出集合推导式

    集合推导式 {k for循环 if 条件}

     

    没有元组推导式

    集合推导式可以帮我们直接⽣生成⼀一个集合. 集合的特点: ⽆无序, 不重复. 所以集合推导式⾃自 带去重功能

    g = (i for i in range(10)) # 生成器表达式
    
    print(g)  # <generator object <genexpr> at 0x0000000009E573B8>
    
    print(g.__next__()) # 0
    print(g.__next__()) # 1
    print(g.__next__()) # 2
    print(g.__next__()) # 3
    print(g.__next__()) # 4
    print(g.__next__()) # 5
    print(g.__next__()) # 6
    print(g.__next__()) # 7
    print(g.__next__()) # 8
    print(g.__next__()) # 9
    # print(g.__next__()) # ??? StopIteration
    
    
    g = (i for i in range(10)) # 生成器表达式

     

     生成器表达式 (重点)
    (结果 for循环 if)

    def func():
        lst = ["衣服%s" % i for i in range(500)]
        yield from lst # 可以把一个可迭代对象分别进行yield返回
    
        lst1 = ["python%s" % i for i in range(18)]
        yield from lst1
    
    
    gen = func()
    print(gen.__next__())##衣服0
    print(gen.__next__())##衣服1

     

  • 相关阅读:
    Atitit 人脸识别 眼睛形态 attilax总结
    Atitit 手机号码选号 规范 流程 attilax总结 v2 r99.docx
    atitit 板块分类 上市公司 龙头企业公司 列表 attilax总结.docx
    Atititi atiitt eam pam资产管理 购物表去年.xlsx
    使用cmd查看电脑连接过的wifi密码(一)
    常见十大web攻击手段 悟寰轩
    常见web攻击方式 悟寰轩
    【MYSQL数据库】MYSQL学习笔记mysql分区基本操作 悟寰轩
    Filter及FilterChain的使用详解 悟寰轩
    启动tomcat spring初始化两次问题(eg:@PostConstruct) 悟寰轩
  • 原文地址:https://www.cnblogs.com/H1050676808/p/10103555.html
Copyright © 2020-2023  润新知