zoukankan      html  css  js  c++  java
  • python学习之路---day12

                   生成器和生成器表达式
    一:生成器
    生成器实质上就是迭代器。
      三种方式获取生成器:
        01:通过生成器函数
        02:通过各种推导式实现生成器
        03:通过数据的转换也可以获取生成器
    eg:普通函数
        def fun()
            print("111")
            return
         ret=func()
         print(ret)
         结果:
         111
         222
     将函数的return  换成yield  就是生成器
         def fun()
            print("111")
            yield
         ret=func()
         print(ret)
         结果:<generator object func at 0x10567ff68>
         打印结果:结果是一个函数名字的内存地址
    原因:由于函数中存在了yield. 那么这个函数就是⼀个⽣成器
                函数. 这个时候. 我们再执⾏这个函数的时候. 就不再是函数的执⾏了.
                ⽽是获取这个⽣成器.如何使⽤呢? 想想迭代器. ⽣成器的本质是迭代器.
                所以. 我们可以直接执⾏__next__()来执⾏
         其实return和yield一样都有返回值,return返回值后,就退出函数,后面的函数就不在执行
         yield 则是在返回  返回值后 ,还给上一个yield 的变量赋值 
    案例结果说明
    例如:
             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)
    
            打印结果:send和__next__()区别:
                1. send和next()都是让⽣成器向下走⼀次
                2. send可以给上⼀个yield的位置传递值, 不能给最后⼀个yield发送值.
                   在第⼀次执⾏⽣
                   成器代码的时候不能使⽤send()
    案例解释
    二:生成器的作用:
    生成器可以用for循环来循环获取内部的元素:
    def func():
                 print(111)
                 yield 222
                 print(333)
                 yield 444
                 print(555)
                 yield 666
            gen = func()  #这里并没有直接执行这个函数,只是获取了这个函数生成器,
            for i in gen:  #在循环这个函数后,生成器才会执行func()这个函数。i才会找gen要值,func才会执行
            print(i)
            结果:
            111
            222
            333
            444
            555
            666
    
    
    

    三:列表推导式:
      例如:
        lst = []
        for i in range(1, 15):
            lst.append(i)
        print(lst)
        这个代码块是,给出一个列表,通过循环,将数字添加到新的列表中去
        001):可以用列表推导式:
         lst = [i for i in range(1, 15)]
            print(lst)
            列表是常用写法:
            [ 结果 for 变量 in 可迭代对象]
        002):列表推导式还可以用来筛选
            获取1-100内所有的偶数
            lst = [i for i in range(1, 100) if i % 2 == 0]
            print(lst)

    四:生成器和列表推导式的区别:
      生成器: 有yield的函数体
        列表推导式:(  [ 结果 for 变量 in 可迭代对象] )
        列表推导式是通过一行来构建我们需要的列表,列表推导式看起来代码简单。但是出了
        错误很难排查!
    五:生成器表达式:
    001):⽣成器表达式和列表推导式的语法基本上是⼀样的. 只是把[]替换成()
          
    gen = (i for i in range(10))
                print(gen)
                结果:
                <generator object <genexpr> at 0x106768f10>
    
                    打印的结果就是⼀个⽣成器. 我们可以使⽤for循环来循环这个⽣成器:
                gen = ("麻花藤我第%s次爱你" % i for i in range(10))
                for i in gen:
                 print(i)
    View Code
    六:⽣成器表达式和列表推导式的区别:
      1. 列表推导式比较耗内存. ⼀次性加载. ⽣成器表达式⼏乎不占⽤内存. 使⽤的时候才分
          配和使⽤内存
        2. 得到的值不⼀样. 列表推导式得到的是⼀个列表. ⽣成器表达式获取的是⼀个⽣成器.

        举个栗⼦.

        
    同样⼀篮⼦鸡蛋. 列表推导式: 直接拿到⼀篮⼦鸡蛋. ⽣成器表达式: 拿到⼀个老⺟鸡. 需要
        鸡蛋就给你下鸡蛋.
        ⽣成器的惰性机制: ⽣成器只有在访问的时候才取值. 说⽩了. 你找他要他才给你值. 不找他
        要. 他是不会执⾏的.
    View Code
    七:总结: 推导式有, 列表推导式, 字典推导式, 集合推导式, 没有元组推导式
       ⽣成器表达式: (结果 for 变量 in 可迭代对象 if 条件筛选)
         ⽣成器表达式可以直接获取到⽣成器对象. ⽣成器对象可以直接进⾏for循环. ⽣成器具有
         惰性机制.
    
    
    
    
    
  • 相关阅读:
    2018.12.17-dtoj-1174-出现或反转后出现在每个字符串中的最长子串
    2018.12.17-dtoj-1173-每个字符串至少出现两次且不重叠的最长子串
    2018.12.17-dtoj-1171-长度不小于k的公共子串的个数
    2018.12.17-dtoj-1170-最长公共子串
    2018.12.17-dtoj-1168-连续重复子串
    欧拉四面体公式
    超级密码 hdu1226 bfs
    糖果大战 hdu1204
    Find The Multiple (poj1426 一个好的做法)
    Life Forms (poj3294 后缀数组求 不小于k个字符串中的最长子串)
  • 原文地址:https://www.cnblogs.com/one-tom/p/9892592.html
Copyright © 2011-2022 走看看