zoukankan      html  css  js  c++  java
  • python生成器

    一,生成器

    1,生成器就是迭代器

    2有两种方式写生成器

     1),生成器函数

    def gen():
        print("我是一个函数")
        return "娃哈哈" # 返回 娃哈哈, 返回给调用者
        print("你好")
        print("你好")
        print("你好")
    ret = gen()
    print(ret) # 娃哈哈
    

      1.生成器函数就是将return换成yield

    def gen():
        print("爽歪歪")
        yield "娃哈哈" # 可以让我们的函数分段运行
        print("酸酸乳")
        yield "AD钙奶"
        print("黄焖鸡米饭")
    
    ret = gen() # 不会执行你的函数, 获取到生成器对象
    # 迭代器不能等价代换
    print(ret)     # <generator object gen at 0x00000195518CFE60> generator 生成器
    print(ret.__next__()) # 必须执行__next__()才可以触发生成器的运行 娃哈哈
    print(ret.__next__()) # 必须执行__next__()才可以触发生成器的运行 AD钙奶
    print(ret.__next__()) # StopIteration 迭代器, 就找yield, 执行不到才会报错                
    

         2.生成器函数的作用

           1)节省内存,2)惰性机制需要__next__()来访问,3)只能往前执行

    1.普通的程序会占用内存
    def buy():
        lst = []
        for i in range(10000):
            lst.append("衣服%s" % i)
        return lst
    lst = buy()
    print(lst)   #会直接打印到衣服10000件,占用内存空间
    2.生成器写的程序可以自定义控制函数
    def gen():
        lst = []
        for i in range(1, 10000):
            lst.append("衣服%s" % i)
            if i % 50 == 0: #  1 2 3 4 5 6 7 8 9 .. 49  50
                yield lst
                lst = [] # 每次生成一个新列表
    g = gen() # 获取到生成器
    print(g.__next__())   #触发生成器打印下一个值
    print(g.__next__())   #需要手动控制输出结果,节省内存
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())
    
    
    3.生成器还可以使用__next__(), send()来访问生成器
    send()可以给上一个yield位置传值
    def func():
        print("水饺")
        a = yield "大馅水饺"
        print("a=", a)
        print("烧饼")
        b = yield "武大郎烧饼"
        print("b=",b)
        print("老婆饼")
        c = yield "只要老婆不要饼"
        print("c=", c)
    gen = func() # 生成器
    print("返回值是:", gen.__next__())
    print("返回值是:",gen.send("混沌面")) #  和__next__()一样也是向下找yield. 给上一个yield传值
    print("返回值是:",gen.send("胡辣汤")) #  和__next__()一样也是向下找yield. 给上一个yield传值
    print("返回值是:",gen.send("马拉")) #  和__next__()一样也是向下找yield. 给上一个yield传值
    4.send()不可以在第一个位置和最后一个位置出现
     最后的yield后的代码是可以执行的但是会报错. StopIteration
    生成器函数里不要写return
    def  func():
        print("哈哈")
        yield  "呵呵"
        print("吼吼")
        return  "嘻嘻" # don't do this!
    gen = func()
    gen.__next__()
    gen.__next__()

     2)各种推导式

         列表推导式 [结果 for循环 if判断]
         字典推导式 {key: value for循环 if判断}
         集合推导式 {key for循环 if判断}
    1)列表推导式
    lst = ["python全栈%s期" %i for i in range(1,17)]
    print(lst)
    lst = [i for i in range(1,21) if i %2==1]
    print(lst)
    lst= [i for i in range(1,100) if i%2==0]
    print(lst)
    lst = ["中岛美雪", "夏川美里", "原由子", "汪峰", "田震","那英","周杰伦"]
    lis=[i for i in lst if len(i)==2]
    print(lis)
    new_list=[ i**2 for i in range(1,20) if i%2==1 ]
    print(new_list)
    lis=[3,6,9]
    lst=[ (el-2,el-1,el-0)  for el in lis ]
    print(lst)
    2)字典表达式
    dic = {"张无忌":"赵敏", "杨过":"小龙女", "郭靖":"黄蓉"}
    dc={  dic[i]:i  for i in dic }
    dc2={ v:k for k,v in dic.items()}
    print(dc)
    print(dc2)
    lst=[11,22,33]
    dcu={ i:lst[i] for i in range(len(lst))}
    print(dcu)

       3)生成器表达式

    #声称器表达式格式(结果 for语句 if语句)
    def func():
        print(111)
        yield 222
    
    g = func()
    print(g.__next__())
    g = func()
    print(g.__next__())
    gg = (i for i in range(10))  #声称器表达式格式(结果 for语句 if语句
    print(list(gg)) 
  • 相关阅读:
    LOL 计蒜客
    cf1486 D. Max Median
    P3567 [POI2014]KUR-Couriers
    dp 求物品组合情况
    黑暗爆炸
    hdu5306 Gorgeous Sequence
    P4609 [FJOI2016]建筑师
    cf 1342 E. Placing Rooks
    重修dp-背包
    acwing 2154. 梦幻布丁
  • 原文地址:https://www.cnblogs.com/liucsxiaoxiaobai/p/9890953.html
Copyright © 2011-2022 走看看