【问题标题】:Problem with iterating generator functions迭代生成器函数的问题
【发布时间】:2020-04-28 20:28:40
【问题描述】:

假设我们有这个生成器函数:

def count_up_to(max):
    count = 1
    while count <= max:
        yield count
        count += 1

现在如果我想调用next() 函数,我必须将count_up_to 函数分配给一个变量,否则输出将始终为“1”。

下面的代码可以正常工作并遍历数字:

counter = count_up_to(10)
print(next(counter))
print(next(counter))
print(next(counter))
.
.
.

但是这个不起作用,一直打印“1”。

print(next(count_up_to(10)))
print(next(count_up_to(10)))
print(next(count_up_to(10)))
.
.
.

但是为什么呢? print(next(counter))print(next(count_up_to(10))) 有什么不同吗?!

【问题讨论】:

  • 在您的最后一个 sn-p 中,您正在为每个打印行重新初始化您的生成器,因此每个 next() 调用都会获得一个全新的迭代器。
  • 当然不一样。在第一种情况下,您创建一个生成器对象并继续重复使用它。在第二种情况下,您每次使用它时都会创建一个新的生成器对象。你似乎已经发现了这一点?你到底有什么不明白的?

标签: python iterator iteration generator


【解决方案1】:

在你上一次的 sn-p 中,你总是创建一个新的生成器,这就是它总是打印“1”的原因。

在第二个中,您将由 count_up_to 返回的生成器分配给变量 count,而不是函数。每次调用 next(count) 时,您都会告诉生成器产生下一个值。

我希望这会有所帮助:)

【讨论】:

  • 但是使用带有函数名的 for 循环是可行的:for num in count_up_to(10): print(num)。据我所知,for循环一直在调用next()函数,为什么在这种情况下它工作正常,但现在当我们手动调用next()函数时?
  • @Sherafati 这是因为 for 循环不会在每次迭代时调用函数。它调用你的函数一次,然后使用生成器获取新值。
  • Python 然后创建一个临时变量并为每次迭代使用相同的生成器。我不完全知道 Python 是如何在内部处理这个问题的,但是你可以像使用生成器一样使用它。
  • @Sherafati 你也可以这样做,例如:list(count_up_tp(10))
  • 因此,当我们使用 for 循环时,它只调用该函数一次并将其分配给一个变量(即“生成器”类型)并继续调用该变量的 next() 函数。对吗?
【解决方案2】:

这是完全预期的行为。让我描述一下原因。

每次调用 count_up_to 都会返回一个从 1 开始的新生成器。

Python REPL 中的简单检查:

>>> count_up_to(100)
<generator object count_up_to at 0x10e28beb0>
>>> count_up_to(100)
<generator object count_up_to at 0x10e28bf00>
>>> count_up_to(100)
<generator object count_up_to at 0x10e28beb0>
>>> count_up_to(100)
<generator object count_up_to at 0x10e28bf00>

看地址。它总是不同的,内存中有 4 个不同的生成器。

所以,count_up_to 函数本身并不是一个生成器,但是当你调用它时它会返回一个生成器。

当您将 count_up_to 调用的结果存储在变量中时,您将存储生成器。此外,您可以从生成器中获取值,存储在变量中。

【讨论】:

    猜你喜欢
    • 2019-02-27
    • 1970-01-01
    • 1970-01-01
    • 2020-03-10
    • 2018-05-16
    • 1970-01-01
    • 2014-11-12
    • 2021-09-30
    • 1970-01-01
    相关资源
    最近更新 更多