zoukankan      html  css  js  c++  java
  • 14 Python之生成器,生成器函数以及推导式

    一.生成器
       本质就是迭代器. 我们可以直接执⾏__next__()来执⾏ 以下⽣成器
    一个一个的创建对象
    创建生成器的方式:
    1.生成器函数
    2.通过生成器 表达式来获取生成器
    3.类型转换(看不到)
    二.生成器函数(重点)   
    深坑:生成器在要值得时候才拿值
    生成器函数中包含yield,返回数据和return差不多:return会立即结束这个函数的执行,yield 表示返回,不会终止函数的执行,可以分段的执行一个函数.
    当函数中包含了yield,次函数就是生成器函数
    坑:生成器函数在执行的时候返回生成器.而不是之直接执行此函数
    函数中包含了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
    send()  ----> 同__next__()开始执行
    send()可以给上一个yield位置传值
    能够向下执行的两个条件:
         __next__(),执行到下一个yield
         send(),执行到下一个yield,给上一个yield位置传值,
    send和__next__()区别: 
    1. send和next()都是让⽣成器向下走⼀次
     2. send可以给上⼀个yield的位置传递值, 不能给最后⼀个yield发送值. 在第⼀次执⾏⽣ 成器代码的时候不能使⽤send()
    def func():
        print("韭菜盒子")
        a = yield "韭菜鸡蛋"
        print("a", a)
        b = yield "韭菜西红柿"
        print("b", b)
        c = yield "火烧"
        yield "GAME OVER"
     
    gen = func()
     
    print(gen.__next__()) # 第一个位置用send没有任何意义
    print(gen.send("篮球")) # 给上一个yield位置传值  "篮球"这个值赋值给a
    print(gen.send("足球"))
     
    ##韭菜盒子
    韭菜鸡蛋
    a 篮球
    韭菜西红柿
    b 足球
    火烧
    生成器中记录的是代码而不是函数的运行
    def func():
                print("我的天哪 ")
     
                yield "宝宝"
     
            gen = func() # 创建生成器.  此时运行会把生成器函数中的代码记录在内存
            当执行到__next__(), 运行此空间中的代码, 运行到yield结束.
     
            优点: 节省内存, 生成器本身就是代码. 几乎不占用内存
            特点: 惰性机制, 只能向前. 不能反复
    三.各种推导式
    列表推导式    [结果 for循环 if]
    #生成列表: python1->python18
    lst = []
    for i in range(1, 19):
        lst.append("python%s期" % i)
     
    print(lst)
    列表推导式 [结果 for循环 if条件]
     
     
    lst = ["python%s期" % i for i in range(1, 19)]
    print(lst)
     
    #生成列表.类表中装的数据是 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)
    字典推导式    {结果(k:v) for循环 if}
    字典推导式
    语法: { 结果(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}
    没有元组推导式
    四.生成器表达式(重点)
    (结果 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
    from   可以把一个可迭代对象分别进行yield返回
    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__())
    print(gen.__next__())
  • 相关阅读:
    用好idea这几款插件,可以帮你少写30%的代码
    面试官:一个TCP连接可以发多少个HTTP请求?
    php5.4、5.5、5.6高版本中htmlspecialchars兼容性处理
    IIS8的SNI功能实现同一服务器多HTTPS站点
    appache 在windows 中无法启动的测试
    lumen 支持多文件上传及php 原生多文件上传
    laravel windows安装
    jQuery 为动态添加的元素绑定事件
    thinkphp 5.0 在appache下隐藏index.php入口代码
    thinkphp5.0 分页中伪静态的处理
  • 原文地址:https://www.cnblogs.com/a2534786642/p/10103559.html
Copyright © 2011-2022 走看看