• Python生成器



    1 生成器

    根据程序员制定的规则循环生成数据,当条件不成立时则生成数据结束。数据不是一次性全部生成处理,而是使用一个,再生成一个,可以节约大量的内存。

    两种方式创建生成器

    1. 生成器推导式
    2. yield 关键字

    2 生成器推导式方式创建生成器:

    • 与列表推导式类似,只不过生成器推导式使用小括号
    # 创建生成器
    my_generator = (i * 2 for i in range(5))
    print(my_generator)
    
    # next获取生成器下一个值
    # value = next(my_generator)
    # print(value)
    
    # 遍历生成器
    for value in my_generator:
        print(value)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    执行结果:

    <generator object <genexpr> at 0x000001AF8E9C9510>
    0
    2
    4
    6
    8
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    说明:

    • 获取生成器下一个值得方法是调用next()
    • 实际上是一个迭代器,因此可用for循环获取生成器值

    3 yield 关键字创建生成器:

    • 只要在def函数里面看到有 yield 关键字那么就是生成器
    def my_g():
        for i in range(3):
            yield i
    
    
    for i in my_g():
        print(i)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    执行结果:

    0
    1
    2
    
    Process finished with exit code 0
    
    • 1
    • 2
    • 3
    • 4
    • 5

    说明:

    • 获取下一个值时,会执行for循环到yield这一行,返回yield后面得值,并阻塞在这一行,获取下一个值时继续往下执行
    • 生成器如果把数据生成完成,再次获取生成器中的下一个数据会抛出一个StopIteration 异常,表示停止迭代异常
    • for 循环内部自动处理了停止迭代异常,相对于while语句,使用起来更加方便

    4 斐波拉契数列(Fibonacci)使用生成器生成

    def fibonacci(num):
        a = 0
        b = 1
        # 记录生成fibonacci数字的下标
        current_index = 0
        while current_index < num:
            result = a
            a, b = b, a + b
            current_index += 1
            # 代码执行到yield会暂停,然后把结果返回出去,下次启动生成器会在暂停的位置继续往下执行
            yield result
    
    
    fib = fibonacci(5)
    # 遍历生成的数据
    for value in fib:
        print(value)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    执行结果:

    0
    1
    1
    2
    3
    
    Process finished with exit code 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    5 生成器的send方法

    generator.send(value)
    恢复执行并向生成器函数“发送”一个值。 value 参数将成为当前 yield 表达式的结果。 send() 方法会返回生成器所产生的下一个值,或者如果生成器没有产生下一个值就退出则会引发 StopIteration。 当调用 send() 来启动生成器时,它必须以 None 作为调用参数,因为这时没有可以接收值的 yield 表达式。

    def test():
        for i in range(5):
            sig = yield i
            print('send by:', sig)
     
     
    a = test()
     
    print(a.__next__()) # 运行生成器,在yield处停止
    print(a.send('a'))  # 将“a”传递给sig变量,并在下一个yield处停止,返回1
    print(a.send('b'))  # 将“b”传递给sig变量,并在下一个yield处停止,返回2
    print(a.__next__()) #
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    执行结果:

    0
    send by: a
    1
    send by: b
    2
    send by: None
    3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  • 相关阅读:
    2023-11-09 mysql-代号m-事务-添加RC隔离级别-需求分析
    CISCO设备信息泄漏漏洞案例2
    《OpenDRIVE1.6规格文档》2
    LUCEDA IPKISS------Definition Properties 表格查询
    计算机视觉(CV)技术的优势和挑战
    代码随想录算法训练营第二十四天| LeetCode77. 组合
    详解 canal 同步 MySQL 增量数据到 ES
    【云原生】Kubernetes CRD 详解(Custom Resource Definition)
    互联网医院|互联网医院建设三级等保不可缺
    上传和下载文件
  • 原文地址:https://blog.csdn.net/ZGL_cyy/article/details/126680300