我有一个这样定义的生成器:

def gen():
    r = [0]
    yield r
    r[0] = 1
    yield r
    r[0] = 2
    yield r


它将产生一个元素的三个列表,从0到2:

>>> a = gen()
>>> next(a)
[0]
>>> next(a)
[1]
>>> next(a)
[2]
>>> next(a)
Traceback (most recent call last):
  File "<pyshell#313>", line 1, in <module>
    next(a)
StopIteration


现在,当我从生成器中列出清单时,得到了以下信息:

>>> list(gen())
[[2], [2], [2]]


也就是说,它似乎每次都会产生最后一个计算值。

这是python的错误还是我缺少什么?

最佳答案

这不是错误,它确实按照您的指示执行。您多次产生相同的对象,因此获得对该对象的多个引用。在第一个代码片段中看不到三个[2]的唯一原因是Python不会及时返回并更改先前的输出以使对象发生突变时匹配。尝试存储在变量中显式调用next时获得的值,并在最后检查它们-您将获得相同的结果。

仅当在迭代器再次推进之后不使用任何产生值时,此类迭代器才有用。因此,我通常会避免使用它,因为在尝试预先计算部分或全部结果时会产生意外的结果(这也意味着它会打破各种有用的技巧,例如itertools.tee和可迭代的拆包)。

关于python - 生成器的python3:list():产生项目更改列表时的奇怪行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7503639/

10-12 23:35