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

    '''普通函数'''
    def func():
        print(111)
        return 222
    
    ret = func()  # 111
    print(ret)  # 222
    111
    222

    '''函数中含有yield就是生成器'''
    def func():
        print(111)
        yield 222
        
    gen = func()
    print(gen)  # <generator object func at 0x0000000006085D00>
    ret1 = gen.__next__()  # 111
    print(ret1)  # 222
    <generator object func at 0x0000000007A8BB48>
    111
    222

    def func():
        print(111)
        yield 22
        print(333)
        yield 444
        
    gen = func()  
    ret = gen.__next__()  # 111
    print(ret)  # 22
    ret2 = gen.__next__()  # 333
    print(ret2)  # 444
    ret3 = gen.__next__()  # StopIteration:  # 值取空,就报StopIteration
    print(ret3)
    111
    22
    333
    444
    
    ---------------------------------------------------------------------------
    StopIteration                             Traceback (most recent call last)
    <ipython-input-25-9050db3134ee> in <module>()
         10 ret2 = gen.__next__()
         11 print(ret2)
    ---> 12 ret3 = gen.__next__()
         13 print(ret3)
    
    StopIteration: 

    '''send和__next__()区别
        1.send和next()都是让生成器向下走一次
        2.send可以给上一个yield的位置传递值,不能给最后一个yield发送值,在第一次执行生成器代码的时候不能使用send()
    '''
    def func():
        print(111)
        a = yield "aaa"
        print("a = ", a)
        b = yield "bbb"
        print("b = ", b)
        c = yield "ccc"
        print("c = ", c)
        yield "Bye"
        
    gen = func()
    print(gen.__next__()) # 111 aaa
    print(gen.__next__()) # a = None bbb
    print(gen.__next__()) # b = None ccc
    print(gen.__next__())  # c = None  Bye
    print(gen.__next__()) # StopIteration
    111
    aaa
    a =  None
    bbb
    b =  None
    ccc
    c =  None
    Bye
    
    ---------------------------------------------------------------------------
    StopIteration                             Traceback (most recent call last)
    <ipython-input-26-e1ddf9d0af94> in <module>()
         14 print(gen.__next__()) # b = bbb ccc
         15 print(gen.__next__())  # c = ccc  Bye
    ---> 16 print(gen.__next__()) # StopIteration
    
    StopIteration: 

    def func():
        print(111)
        a = yield "aaa"
        print("a = ", a)
        b = yield "bbb"
        print("b = ", b)
        c = yield "ccc"
        print("c = ", c)
        yield "Bye"
        
    gen = func()
    print(gen.__next__())  # 111 aaa
    ret1 = gen.send("apple")  # a = apple 
    print(ret1)  # bbb
    ret2 = gen.send("banana")  # b = banana
    print(ret2)  # ccc
    ret3 = gen.send("orange")  # c = orange
    print(ret3)  # Bye
    ret4 = gen.send("pear")  # StopIteration
    111
    aaa
    a =  apple
    bbb
    b =  banana
    ccc
    c =  orange
    Bye
    
    ---------------------------------------------------------------------------
    StopIteration                             Traceback (most recent call last)
    <ipython-input-27-3a8a2fe89824> in <module>()
         17 ret3 = gen.send("orange")  # c = orange
         18 print(ret3)  # Bye
    ---> 19 ret4 = gen.send("pear")  # StopIteration
    
    StopIteration: 

    '''生成器可以使用for循环去内部的元素'''
    def func():
        print(111)
        yield 222
        print(333)
        yield 444
        print(555)
        yield 666
        
    gen = func()
    for i in gen:
        print(i)
    111
    222
    333
    444
    555
    666
    '''yield在循环体内'''
    def func(n):
        print("start...")
        count = 0
        while count < n:
            count += 1
            yield count
        print("end...")
    
    g = func(5)
    
    for i in g:  #for循环本质就是next下一个元素
        print(i)
    
    返回结果:
    start...
    1
    2
    3
    4
    5
    end...
    '''注意区分send()给上一个yield位置传递一个值,yield是向外返回一个值'''
    def func():
        print("apple")
        y1 = yield 2
        print(y1, " = banana")
        y2 = yield 1
        print(y2, " = orange")
        y3 = yield 3
        print(y3)
    
    g = func()
    print(g.__next__())
    print(next(g))
    print(g.send("big"))
    
    返回结果:
    apple
    2
    None  = banana
    1
    big  = orange
    3
    '''生成器表达式(结果 for循环 if语句)'''
    # lst = [i*i for i in range(5)]
    # print(lst) #列表生成式,直接生成一个列表,下面把中括号换为小括号,就是一个生成器
    # g = (i*i for i in range(5))
    # print(g) #生成器对象,省内存
    # print(next(g))
    # print(next(g))
    # print(next(g))
    # print(next(g))
    # print(next(g))
    # print(next(g)) #StopIteration
    '''yield from是将列表中的每一个元素返回'''
    def gen():
        lst = ["apple", "banana", "pear", "orange"]
        yield from lst
        
    g = gen()
    for i in g:
        print(i)
    apple
    banana
    pear
    orange
    def gen():
        lst = ["apple", "banana", "orange", "pear"]
        lst2 = ["peach", "watermelon", "strawberry", "blueberry"]
        yield from lst
        yield from lst2
        
    g = gen()
    print(list(g))  # ['apple', 'banana', 'orange', 'pear', 'peach', 'watermelon', 'strawberry', 'blueberry']
    ['apple', 'banana', 'orange', 'pear', 'peach', 'watermelon', 'strawberry', 'blueberry']
    '''
    一个面试题,难度系数50000000000颗星
    '''
    # def add(a, b):
    #     return a + b
    #
    # def test():
    #     for r_i in range(4):
    #         yield r_i
    #
    # g = test() #g是一个生成器,也是一个迭代器
    #
    # for n in [2, 10]:
    #     g = (add(n, i) for i in g)
    #
    # print(list(g))
    '''
    分析,当n=2时, g = (add(n, i) for i in g) 右边是一个生成器表达式, g就是一个生成器
    当n=10时, g = (add(n, i) for i in (add(n, i) for i in g)) 右边是一个生成器表达式, g就是一个生成器
    当程序执行到list(g)时,开始取生成器里的值
    当n=10时,g = (add(10, i) for i in (add(10, i) for i in g))
    g = (add(10, i) for i in (10, 11, 12, 13))
    g = (20, 21, 22, 23)
    所以打印出来的值就是[20, 21, 22, 23]
    '''
  • 相关阅读:
    Linux学习之路:shell变量(二)环境变量
    LVS配置与安装
    Linux学习之路:shell变量(一)
    SQL Server用存储过程新建视图
    【转】SQL Server 2012 配置AlwaysOn(三)
    【转】SQL 语句:Alter table
    Linux学习之路:认识shell和bash
    【转】Centos配置yum源
    【Azure 应用服务】App Service 无法连接到Azure MySQL服务,报错:com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
    【Azure API 管理】在APIM 中添加 logtoeventhub 策略,把 Request Body 信息全部记录在Event Hub中
  • 原文地址:https://www.cnblogs.com/lilyxiaoyy/p/10762493.html
Copyright © 2011-2022 走看看