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


    生成器
    本质就是迭代器.
    一个一个的创建对象
    创建生成器的方式:
    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

     

  • 相关阅读:
    Nginx专题(二)-----虚拟主机、location规则、rewrite、负载均衡配置
    Nginx专题(一)-----简介
    springMVC自动转义问题
    Tomcat专题(三)-----Tomcat性能优化
    Tomcat专题(二)-----Tomcat源码、嵌入式Tomcat
    Tomcat专题(一)-----架构体系
    jvm性能调优(五)-----深入了解性能优化
    jvm性能调优(四)-----编写高效的java代码
    jvm性能调优(三)-----JVM的执行子系统
    jvm性能调优(二)-----垃圾回收、内存分配
  • 原文地址:https://www.cnblogs.com/H1050676808/p/10103555.html
Copyright © 2020-2023  润新知