我有一个这样定义的生成器:
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/