zoukankan      html  css  js  c++  java
  • day13

    1. 生成器

    # 生成器的本质就是迭代器
    # 生成器的特点和迭代器一样,取值方式和迭代器一样(__next__(), send(): 给上一个yield传值
    # 生成器其实就是手写的迭代器
        
    生成器的三种生成办法:
        1.通过生成器函数*
        2.通过生成器表达式创建生成器*
        3.通过数据转换(这次没学)

    2. 生成器函数

    1. 什么是生成器函数
      # 函数中有yield,name这个函数就是生成器函数
      def
    func():    print("我是周杰伦")    yield "昆凌" # 函数中包含了yield, 当前这个函数就不再是普通的函数了. 是生成器函数    print("我是王力宏")    yield "李云迪???"    print("我是笛卡尔积")    yield "笛卡尔积是谁"   # print("你好啊") # 最后一个yield之后如果再进行__next__ 会报错   g = func() # 不会执行函数, 拿到的是生成器.   print(g.__next__()) # 周杰伦   print(g.__next__()) # 王力宏   print(g.__next__()) # 笛卡尔积   print(g.__next__()) # 执行下一个yield   # 函数中如果有yield 这个函数就是生成器函数. 生成器函数() 获取的是生成器. 这个时候不执行函数   # return 直接返回结果, 结束函数的调用   # yield 返回结果, 可以让函数分段执行   # g.__next__() # 执行函数. 执行到下一个yield   # g.__next__() # 继续执行函数到下一个yield
    2. 生成器的好处之一: 不占用内存

      #
    一次性拿出所有的放在列表里,占用内存   def order():    lst = []    for i in range(1000):    lst.append("衣服" + str(i))    return lst   ret = order()   print(ret)   # 生成器,一次拿出一个,不占用内存   def order():    for i in range(1000):    yield "衣服" + str(i)   g = order() # 获取生成器,不执行函数   mingwei = g.__next__()   print(mingwei) # 衣服0   zhaoyining = g.__next__()   print(zhaoyining) # 衣服1
    3. send()方法
        # send() 和 __next__是一样的. 可以执行到下一个yield
        # send() 还可以给上一个yield位置传值, 不能给最后⼀个yield发送值. 在第⼀次执⾏⽣成器代码的时候不能使⽤send()
        
        例1:
            def func():
                print("我是第一段")
                a = yield 123
                print(a)
                print("闫子哲是第二段")
                b = yield 456
                print(b)
                print("理想是第三段")
                c = yield 789
                print(c)
                print("刘伟是最后一段")
                d = yield 666   # 最后收尾一定是yield
    
            g = func()  # 获取生成器,不执行函数
    
            print(g.__next__()) # 没有上一个yield 所以不能使用send() 开头必须是__next__()
            print(g.send("煎饼果子"))
            print(g.send("韭菜盒子"))
            print(g.send("锅包肉"))
    
        例2:
            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)
    4. 拿生成器里所有的东西

      def func(): yield 1 yield 13 yield 26 yield 88 yield 46 # 现在func() 是生成器,然后for迭代生成器 for i in func(): # for的内部一定有__next__() print(i) 结果: 1 13 26 88 46 # 还可以这样拿所有值 print(list(func())) # 内部都有__next__() 结果: [1, 13, 26, 88, 46]

     4. 各种推导式

    1. 列表推导式
        lst = []
        for i in range(1, 16):
            lst.append("python" + str(i))
        print(lst)
        
        列表推导式: 用一句话生成一个列表
        lst = ["python"+str(j) for j in range(1, 16)]
        print(lst)
        
        语法: [结果 for循环 判断]
        
        例1:
        # 100以内的奇数
        lst = [i for i in range(100) if i%2==1]
        print(lst)
        
        例2:
        # 100以内能被3整除的数的平方
        lst = [i*i for i in range(100) if i%3==0]
        print(lst)
    
        例3:
        # 寻找名字中带有两个e的⼈的名字
        names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven','Joe'],
                 ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
    
        # for循环完成
        lst = []
        for line in names:
            for name in line:
                if name.count("e") == 2:
                    lst.append(name)
        print(lst)
    
    
        # 列表推导式完成
        lst = [name for line in names for name in line if name.count("e") == 2]
        print(lst)
    2. 字典推导式
        # 把[11, 22, 33, 44] 变成 {0:11,1:22,2;33}
        lst = [11, 22, 33, 44]
        dic = {i:lst[i] for i in range(len(lst)) if i < 2}  # 字典推导式就一行
        print(dic)
        
        语法: {k:v for循环 条件筛选}
    
        例1:
        # 把key和value位置反过来
        dic = {"JJ": "林俊杰", "jay": "周杰伦", "zs": "赵四", "ln": "刘能"}
        dic = {v: k for k, v in dic.items()}
        print(dic)
    3. set(集合)推导式
        首先再来回顾一下set(集合):
                1. set去重复
                2. set本身是不可哈希的(可变的)
                3. set中的元素是可哈希的(不可变的)
    
        # 集合推导式
        s = {i for i in range(100)}  # 可去重复
        print(s)
    
        语法: {i for循环 条件判断}
    
        例: 将数据去重
       lst
    = [1, 1, 4, 6, 7, 4, 2, 2]    # 转换成集合再转换回去 s = set(lst)  print(s)  结果: {1, 2, 4, 6, 7}  # 直接用集合推导式  s = {el for el in lst}  print(s) 结果: {1, 2, 4, 6, 7}

    5. 生成器表达式

        # 生成器表达式
        tu = (i for i in range(10))  # 没有元组推导式.  生成器表达式
        print(tu)  # 生成器
        print(tu.__next__())  # 0
        print(tu.__next__())  # 1
        print(tu.__next__())  # 2
        print(tu.__next__())  # 3
        print(tu.__next__())  # 4
        print(tu.__next__())  # 5
        print(tu.__next__())  # 6
        print(tu.__next__())  # 7
        print(tu.__next__())  # 8
        print(tu.__next__())  # 9
        print(tu.__next__())  # 第11个报错
    
        # 生成机制比较
        lst = [i for i in range(10)]  # 列表一下子拿出所有值
        print(lst)
        结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    
        gen = (i for i in range(10))  # 生成器, 惰性机制(要一个值,给一个值)
        print(gen.__next__())
        结果: 0
    # 深坑==> ⽣成器. 要值得时候才拿值. (这个值拿过就没有了)
    
    例1:
        # 生成器函数
        def func():
            print(111)
            yield 222
            yield 333
    
        g = func()  # 获取生成器
        g1 = (i for i in g)  # 生成器
        g2 = (i for i in g1)  # 生成器
    
        print(list(g))  # ??? [222]. g从源头func()把数据拿走了
        print(list(g1))  # ??? []  g1找g要数据,g找源头拿数据,源头已经没有数据了
        print(list(g2))  # ??? []  同理g1
    
    例2:
    # 分析这道面试题
        # 求和
        def add(a, b):
            return a + b
    
        # 生成器函数  # 0-3
        def test():
            for r_i in range(4):
                yield r_i
    
        # 0,1,2,3
        g = test()  # 获取生成器
    
        #
        for n in [2, 10]:
            g = (add(n, i) for i in g)
    
        # 到最后往里面放值就对了(不到最后不往里面放值)
        print(list(g))  # 获取生成器里面的所有值
        结果: [20, 21, 22, 23]    
       print(list(g)) # g里面的东西取完了 第二次再拿就是[] 结果: []
  • 相关阅读:
    Linux 环境下umount, 报 device is busy 的问题分析与解决方法
    WScript与CScript的区别
    20170803上课笔记
    20170802上课随笔
    20170801上课笔记
    20170731上课笔记
    20170729上课笔记
    20170727上课笔记
    20170726上课笔记
    20170725上课笔记
  • 原文地址:https://www.cnblogs.com/kangqi452/p/11312388.html
Copyright © 2011-2022 走看看