我有一个像这样定义的生成器:
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 bug还是我错过了什么?
答案 0 :(得分:2)
这不是一个错误,它完全按照你的要求去做。您将多次产生相同的对象,因此您可以获得对该对象的多个引用。您在第一个片段中看不到三个[2]
的唯一原因是Python不会及时返回并更改先前的输出以匹配对象发生变化时的情况。尝试存储在变量中明确调用next
时获得的值,并在最后检查它们 - 您将得到相同的结果。
这样的迭代器仅在迭代器再次前进后没有使用生成值时才有用。因此,我通常会避免使用它,因为它在尝试预先计算某些或所有结果时会产生意外结果(这也意味着它会破坏各种有用的技巧,例如itertools.tee
和可迭代的解包)。
答案 1 :(得分:0)
你想:
def gen():
for i in (0,1,2):
yield [i]
这将产生三个列表,而不是三个列表。