zoukankan      html  css  js  c++  java
  • 生成器和生成器表达式

    # 生成器本质就是迭代器
    # 第一种方法通过函数来获取生成器
    
    def fun1():
        print('111')
        yield '222'
        print('333')
        yield '444'
    
    
    g = fun1()
    # 函数不会执行而是获取生成器
    print(g)
    # fun1是生成器函数,而g就是生成器 <generator object fun1 at 0x000001D1E2F1B3C8>
    print(g.__next__())
    print(g.__next__())
    # 当执行nextAPI的时候函数才会执行,yield是返回值
    # yield和return都是来返回值区别是什么?yield是分段执行函数而return是直接停止函数
    # 函数生成器可以使用send方法传值
    def fun2():
        a = yield '222'
        print('a=',a)
        b = yield '444'
        print('b=',b)
        yield '666'
    
    g = fun2()
    print(g.__next__())
    print(g.send('首次传值'))
    print(g.send('二次传值'))
    
    # 222
    # a= 首次传值
    # 444
    # b= 二次传值
    # 666
    
    # 打印结果,send同样是执行下一段代码,这里next执行的时候,代码到yield '222'停止运行
    # yield返回值并且终止一段代码,到send执行a = 赋值
    # 列表推导式
    lst  = ['三年级%s班' %i for i in range(1,8)]
    # print(lst)
    # ['三年级1班', '三年级2班', '三年级3班', '三年级4班', '三年级5班', '三年级6班', '三年级7班']
    # 相当于
    lst = []
    for i in range(1,8):
        lst.append('三年级%s班' %(i))
    print(lst)
    
    # 生成器推导式
    gen = ('返回值是%s' %(i) for i in range(1,15) if i % 3 == 0)
    # 在推导式中可以用if进行筛选
    # 相当于
    
    def fun3():
        for i in range(1,15):
            if i %3 == 0:
                yield '返回值是%s' %(i)
    
    gen1 = fun3()
    print(list(gen))
    print(list(gen1))
    # ['返回值是3', '返回值是6', '返回值是9', '返回值是12']
    # 我们将生成器变成列表后的结果,两次结果相同
    # 生成器只有在要值的时候才会取值,且生成器的next指针只能向下取值,也就是只能取一次值
    def fun4():
        print(111)
        yield 222
    
    g = fun4()
    
    g1 = (i for i in g)
    g2 = (i for i in g1)
    
    print(list(g))
    print(list(g1))
    print(list(g2))
    
    # 111
    # [222]
    # []
    # []
    # 打印的结果,因为fun4是生成器函数,只有在取值的时候才会执行,list(g),将生成器转换为列表,这时候需要取值
    # 所以执行了生成器函数,并且将返回值222取出,这时候生成器中就没有值了,也就是next指针无法向下继续走了,所以g2,g3都是空
    
    # 字典推导式
    dic = {i - 1:i for i in [1,2,3,4,5,6] if i %2 == 0}
    print(dic)
    
    # 集合推导式
    
    lst = [1,2,3,4,5,5,6,6]
    s = {i for i in lst}
    print(s)
    # 集合推导式,去重
    def add(a,b):
        return a + b
    
    def test():
        for r in range(4):
            yield r
    
    g = test()
    
    for n in [2,5]:
        g = (add(n , i) for i in g)
    
    print(list(g))
    
    #结果 [10, 11, 12, 13]
    
    # 首先在利用生成器函数获得一个生成器
    # 这个时候执行循环,我们知道生成器的惰性机制,只有在next和send的取值时候才会执行
    # 所以这时候for循环执行的时候生成器不会执行
    # 这个时候我们debug一下
    # test() = <generator object test at 0x000001C8142DDEC8>
    # 当循环执行完一遍后我们发现生成器的内存地址发生了变化<generator object <genexpr> at 0x000001C814A57448>
    # 因为生成器表达式的惰性机制他没有取值操作,但却进行了表达式的置换简单来说当循环结束后表达式
    g = (add(n , i) for i in (add(n ,i) for i in test()))
    # 生成器没有取值,但却会不停的嵌套,当你运行next的时候才会进行取值,循环结束后n = 5
    # print(g.__next__()) result:10,这个地方for循环是个烟雾弹,在执行for循环的时候生成器不停的嵌套但却不会真正运算或者取值
    # 这也是生成器性能高的地方
  • 相关阅读:
    activiti--操作例子
    activiti--服务表
    spring--加载资源文件
    Day17
    Day15
    Day14
    Day13
    Day12
    Day16
    Day11
  • 原文地址:https://www.cnblogs.com/tengx/p/11688971.html
Copyright © 2011-2022 走看看