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

    生成器

    简述

    如果函数中有yield关键字,那么这个函数就是生成器函数,

    每次调用该函数都会返回一个生成器对象。

    生成器是一个迭代器,但是迭代器不一定是一个生成器

    举个栗子

    def gen():
        for i in range(0, 3):
            yield i
    
    gen1 = gen()
    gen2 = gen()
    print(gen1, gen2)
    #<generator object gen at 0x00000000024C01B0> <generator object gen at 0x00000000024C04F8>

    生成器工作原理

    以下面的代码为例来说明

    def gen():
        print("starts")
        yield 1
        print("continue")
        yield 2
        print("end")
    
    gen1 = gen()
    print(next(gen1)) #start 1
    print(next(gen1)) #continue 2
    print(next(gen1)) #StopIteration

    说明

    (1)当调用生成器函数时,会创建一个生成器对象(gen1),这个对象包装生成器函数的定义体

    (2)当把生成器对象传递给next函数时,生成器函数会向前执行函数定义体中的下一个yield语句,返回生成的值,并在当前位置暂停

    (3)最终函数定义体返回时,外层的生成器对象抛出StopIteration异常

    生成器特性

    (1)保存执行上下文

    def fib():
        a, b = 0, 1
        while True:
            yield b
            a, b = b, a + b
    
    gen = fib()
    print(next(gen)) #1
    print(next(gen)) #1
    print(next(gen)) #2
    print(next(gen)) #3
    print(next(gen)) #5
    print(next(gen)) #8
    print(next(gen)) #13
    print(next(gen)) #21

    (2)利用next函数与调用的代码进行交互

    生成器解析

    gen = (i for i in range(10))
    print(gen) #<generator object <genexpr> at 0x00000000020B01B0>
    print(type(gen)) #<class 'generator'>
    print(next(gen)) #0
    print(next(gen)) #1

    应用场景

    每次你需要返回一个序列的函数或在循环中运行的函数时,都应该考虑到生成器

    栗子1

     使用生成器的数据流缓冲

    使用这些数据的第三方代码可以暂停、恢复、和停止生成器,在开始这一过程之前无需导入所有的数据

    栗子2

    对于基于某些序列的数据转换算法,生成器有助于降低算法的复杂度并提高效率

    参考资料:《python高级编程》

  • 相关阅读:
    register变量
    register变量
    const和volatile是否可以同时修饰一个变量?有什么特殊含义?
    关于多态性和虚函数的理解
    static全局变量与普通的全局变量有什么区别
    《c专家编程》学习笔记
    正则表达式入门学习
    mvc ActionResult
    ASP.NET MVC:通过 FileResult 向 浏览器 发送文件(传)
    Asp.net mvc 中的HttpContext
  • 原文地址:https://www.cnblogs.com/marton/p/10744858.html
Copyright © 2011-2022 走看看