为什么这个python生成器每次都返回相同的值?


问题内容

我有这个生成器产生列表:

def gen():
    state = [None]

    for i in range(5):
        state[0] = i
        yield state

这是我调用它时的输出:

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

为什么所有元素[4]?不是[[0], [1], [2], [3], [4]]吗?


问题答案:

您正在重用同一列表对象。生成器一遍又一遍地返回一个对象,对其进行操作,但是对该对象的任何其他引用都会看到相同的变化:

>>> r = list(gen())
>>> r
[[4], [4], [4], [4], [4]]
>>> r[0] is r[1]
True
>>> r[0][0] = 42
>>> r
[[42], [42], [42], [42], [42]]

产生列表的 副本 或创建一个新的新鲜列表对象,而不是操作一个对象。

def gen_copy():
    state = [None]

    for i in range(5):
        state[0] = i
        yield state.copy()  # <- copy

def gen_new():
    for i in range(5):
        state = [i]  # <- new list object every iteration
        yield state