zoukankan      html  css  js  c++  java
  • Python yield

    在 Python 中,使用了 yield 的函数被称为生成器 (generator)。

    跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单的理解生成器就是一个迭代器。

    在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值,并在下一次执行 next() 方法时从当前位置继续运行

    调用一个生成器函数,返回的是一个迭代器对象。



    实例:斐波那契数列

    斐波那契数列是一个简单的递归,除第一个和第二个数外,任意一个数可由前两个数相加得到。


    方法1:简单输出斐波那契数列的前 N 个数

    def fab(max):
        n, a, b = 0, 0, 1
        for n in range(max):
            print(b)
            a, b = b, a+b
            n = n+1
    fab(5)
    

    输出:

    1
    1
    2
    3
    5
    

    使用 print 打印导致该函数可复用性较差,因为 fab 函数返回 None,其他函数无法调用。


    方法2:通过列表返回

    def fab(max):
        n, a, b = 0, 0, 1
        L = []
        for n in range(max):
            L.append(b)
            a, b = b, a+b
            n = n+1
        return L
    
    for i in fab(5):
        print(i)
    

    输出:

    1
    1
    2
    3
    5
    

    返回 list 能满足复用性要求,但该函数在运行中占用的内存会随着参数 max 的增大而增大。

    如果要控制内存,不要用 List 来保存中间结果,而是通过 iterable 来迭代


    方法3:通过 iterable 对象来迭代

    利用 iterable 把 fab 函数改写为一个 iterable 的 class。

    class Fab(object):
        def __init__(self, max):
            self.max = max
            self.n, self.a, self.b = 0, 0, 1
    
        def __iter__(self):
            return self
    
        def __next__(self):
            if self.n < self.max:
                r = self.b
                self.a, self.b = self.b, self.a+self.b
                self.n = self.n + 1
                return r
            raise StopIteration()
    
    for n in Fab(5):
        print(n)
    

    输出:

    1
    1
    2
    3
    5
    

    Fab 类通过 __next()__ 不断返回数列的下一个数,内存占用始终为常数。

    但是 class 改写的版本,代码比较繁琐。

    既想保持代码的简洁,又想获得 iterable 的效果,使用 yield


    方法4:yield

    def fab(max):
        n, a, b = 0, 0, 1
        for n in range(max):
            yield b
            a, b = b, a+b
            n += 1
    
    for n in fab(5):
        print(n)
    

    输出:

    1
    1
    2
    3
    5
    

    仅把第一种方法的 print(b) 改为 yield b,即保持了代码的简洁性又获得了 iterable 的效果。

  • 相关阅读:
    ZOJ 2770 Burn the Linked Camp 差分约束
    作业04 一个简单的扑克牌游戏
    C++友元
    ZOJ 3645高斯消元
    CodeForces 55D 数位统计
    03类的设计和使用
    HDU 4522
    POJ 2559单调栈
    PL/SQL REPORT 开发模拟登陆
    修改报表心得
  • 原文地址:https://www.cnblogs.com/keye/p/15623831.html
Copyright © 2011-2022 走看看