【问题标题】:Can a current generator value interact with the value generated before it?当前生成器值可以与之前生成的值交互吗?
【发布时间】:2019-02-08 01:05:22
【问题描述】:

我知道 yield 会即时生成一个值,据我了解,这意味着它不会将值保存在内存中,因此当前值不应该能够交互最后的值。

但我只是想确定是这样,有人可以确认这是否可能吗?

我将使用 5 作为 number 中的值。

没有生成器的示例:

def factorial(number):
    result = number
    if number <= 1:
        return 1
    else:
        for x in reversed(range(1, number)): # (4,1) reversed
            result *= x # 5*4*3*2*1
    return result # returns 120

是否可以通过使用 yield 函数来做同样的事情?怎么样?

谢谢

【问题讨论】:

  • 但是factorial() 使用生成器有什么意义呢?你将把它当作一个函数来使用——你不会用它来迭代或生成任何东西。为什么要使用产量?
  • “据我了解,这意味着它不会将值保留在内存中” - 正确。 “因此当前值不应与最后一个值交互” - 不正确。这就是变量的用途。 “没有生成器的示例:” - 不正确。 reversedrange 都是生成器。如果你的意思是把factorial 变成一个生成器,因为它只返回一个值,把return 转换成yield 就可以了。你的意思是一个生成连续阶乘的生成器,你可以像factorial(range(10))一样调用它?
  • @Amadan 我希望我能给你和 Primusa 一个适当的答复,但我的知识有限,我只是在看一个关于 yield 函数的视频,这个人表明在大循环上return 函数需要更长的时间和更多的内存使用,而 yield 函数是即时的,几乎没有内存使用,在我原始帖子的示例中,如果你要对 200,000 之类的因子进行阶乘,则需要几秒钟,所以我想知道它是否可以使用yield立即获得
  • 如果你要返回一个包含 200000 个元素的 list,那会占用一些内存。 生成 200000 个元素需要相同的工作量,但是如果您使用相同的算法,您可以对其进行切片。这就是为什么我说生成器通常只在您可能有多个值的情况下才有意义——总是只返回一个值的生成器不是很有用。
  • 说你要200000块砖;如果您希望将它们交付,将它们放在卡车中(占用空间)并立即将它们全部交给您是有意义的。在建筑工地上,一个人把它们放在墙上,然后用砂浆拍打它们,你希望它们在你需要的时候一个接一个地交给你,而不是一下子倾倒在你身上。

标签: python generator yield


【解决方案1】:

生成器可以是有状态的:

def fibs():
    a, b = 1, 1
    while True:
        yield b
        a, b = b, a + b

g = fibs()

for i in range(10):
    print next(g)

这里的状态是在局部变量中。它们在生成器生成的迭代器处于活动状态时保持活动状态。

编辑。我是盲目的,这是一个阶乘

def factorials():
    i = 1
    a = 1
    while True:
        yield a
        i+=1
        a*=i

或者如果你需要一个函数而不是它们的流,那么这里是一个单行

print reduce(lambda a, b: a*b, (range(1, 10+1)))

【讨论】:

  • 注意:实际上我们不计算阶乘,我们只是将前 100 个存储在一个表中。它们增长得如此之快,以至于较大的唯一用例是数字理论。在这种情况下,您可以使用特定领域的东西,例如从素数分解中计算它们。
猜你喜欢
  • 1970-01-01
  • 2016-05-27
  • 2018-11-13
  • 2019-04-30
  • 1970-01-01
  • 2012-12-19
  • 2012-01-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多