【问题标题】:Python yield keyword significance and confusion about generators?Python yield 关键字的意义和关于生成器的困惑?
【发布时间】:2020-07-05 02:55:26
【问题描述】:

我很困惑为什么我们不说yield b,如果我删除yield a会有什么不同?

我只是对它们与正常功能的比较感到困惑?

def fibonacci(n):
    """ A generator for creating the Fibonacci numbers """
    a, b, counter = 0, 1, 0
    while True:
        if (counter > n): 
            return
        yield a
        a, b = b, a + b
        counter += 1
f = fibonacci(5)
for x in f:
    print(x, " ", end="") # 
print()

【问题讨论】:

  • 看起来a 包含序列中的“当前”数字,而b 包含“下一个”数字。
  • 可以yield b;这是您的函数最终想要产生的值。但是,如果您这样做了,您将不得不在下一次迭代中以某种方式跳过 yield a,因为它与当前迭代中的 b 值相同。

标签: python python-3.x iterator generator


【解决方案1】:

正常的功能看起来几乎相同:

def fibonacci(n):
    """ A function for creating the Fibonacci numbers """
    a, b, counter = 0, 1, 0
    numbers = []
    while True:
        if (counter > n): 
            return numbers
        numbers.append(a)
        a, b = b, a + b
        counter += 1

b仅用于跟踪进程的内部状态。 a 是唯一通过迭代器或返回值直接公开的值,b 仅用于计算 a

常规函数计算所有请求的斐波那契数,然后将它们存储在一个列表中并将该列表返回给调用者。如果n 很大,这可能需要大量时间和内存。

另一方面,生成器函数几乎立即返回,因为它还没有计算任何东西。它只返回了一个generator 实例,当传递给next 时,它将计算序列中的下一个斐波那契数并返回它,然后继续等待,直到您再次调用next。它只使用少量、恒定的内存,每次调用 next 只需要执行少量添加所需的时间。

【讨论】:

  • 那么我们为什么还要使用相同的生成器呢?这就是我困惑的地方!
  • 它们相同,但定义看起来相似。该函数在返回之前创建所有请求的斐波那契数列。生成器函数创建一个生成器,它只会在迭代时计算每个实际请求的数字。
  • 所以它们是 c++ 中的 void 函数,但具有保存结果的能力,就好像它们是通过引用传递的一样,对吧?
  • 不完全是,假设“void function”是指不返回值的函数。 fibonacci 仍然返回一个值,但该值与协程非常相似,类似于函数,但更通用,您可以暂停其执行并稍后恢复它,而不必退出并重新启动。跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-30
  • 2011-11-02
  • 1970-01-01
  • 1970-01-01
  • 2017-09-07
  • 2019-12-04
  • 1970-01-01
相关资源
最近更新 更多