zoukankan      html  css  js  c++  java
  • yield用法与生成器

    参考链接1
    参考资料: 《dive into python3》

    1 基本用法

    1.1 可迭代对象

    当你用列表生成式来建立列表时就生成了一个可迭代对象,如下,counter_list就是一个可迭代对象,

    counter_list = [x*x for x in range(5)]
    for i in counter_list:
        print(i) 
    

    这里所有的值都存在内存当中,所以并不适合大量数据

    1.2 生成器(generator)

    对此较好的解决方法就是生成器,它具有以下特点:

    • 可迭代

    • 只能读取一次

    • 实时读取数据,不全存在内存中

    这样一来生成器的一大好处就是节省内存XD。

    1.3 yield关键字

    yield是一个类似于return的关键字,但是返回的只是上面所讲的生成器

    def make_counter(x):
        print('entering make_counter')
        while True:
            yield x*x
            print('incrementing x')
            x=x+1
    
    counter = make_counter(0)
    
    print(counter) 
    

    如上,最后输出结果如下

    <generator object make_counter at 0x108627c50>
    

    1.4 next()函数

    next()函数以一个生成器对象为参数,并返回其下一个值。

    def make_counter(x):
        print('entering make_counter')
        while True:
            yield x*x
            print('incrementing x')
            x=x+1
    
    counter = make_counter(0)
    
    print(next(counter))
    

    如上,对counter生成器第一次调用next(),它将针对第一条yield语句执行make_counter()中的代码,并返回x*x这个值,并且到此为止,最后输出结果如下

    entering make_counter
    0
    

    对同一生成器反复调用会从上次开始的位置继续,直到下一条yield语句,如下

    def make_counter(x):
        print('entering make_counter')
        while True:
            yield x*x
            print('incrementing x')
            x=x+1
    
    counter = make_counter(0)
    
    print(next(counter))
    print(next(counter))
    

    注意是返回到循环语句中开始,相对于只是将循环语句独立出来分步进行,输出结果如下:

    entering make_counter
    0
    incrementing x
    1
    

    1.5 for循环输出

    for循环能够连续输出,即相当于一直next并输出,注意要设定一个终止条件flag,例如这里的max,如下斐波那契数列:

    def fib(max):
        a,b=0,1
        while a < max:
            yield a  # 跟return类似,详见yield用法笔记
            a,b=b,a+b
    
    ## 测试
    if __name__ == '__main__':
        for n in fib(1000):
            print(n,end=' ')
        print('
    ')
    

    1.6 list()函数输出

    将生成器传给list函数,它将遍历整个生成器(就像上面的for循环)并返回包含所有数值的列表,如下

    def fib(max):
        a,b=0,1
        while a < max:
            yield a  # 跟return类似,详见yield用法笔记
            a,b=b,a+b
    
    ## 测试
    if __name__ == '__main__':
        print(list(fib(1000)))
    

    2 与return的区别

    yield用法跟return类似,都会返回值,但是会有以下几点区别

    • return语句象征着函数的结束
    def call(i):
        return 2*i
    # 从这一行开始不属于函数call部分
        i=i+1
        print(i)
        return 2*i
    print(call(4))
    
  • 相关阅读:
    Sql2008 全文索引 简明教程
    sql server 全文检索 使用
    数据库分词查询的优缺点以及英文和中文各自的分词方法(一)
    win10中打开SQL Server配置管理器方法
    Asp.net 中高亮显示搜索关键字简单方法
    EntityFramework优缺点
    LoadXml载入Xhtml文件速度很慢
    c#无限循环线程如何正确退出
    线程的等待方法:join
    C#如何优雅的结束一个线程
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13281734.html
Copyright © 2011-2022 走看看