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

问题描述 投票:8回答:2

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

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]]

python generator yield
2个回答
8
投票

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

>>> 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

4
投票

你是yielding相同的list/object所以你总是看到添加到列表中的最后一个值。你应该得到一份副本:

yield state.copy()

或者在第一个循环中创建列表:

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

每次创建新的列表/对象都很容易:

def gen():
    for i in range(5):
        state = [None]
        state[0] = i
        yield state
© www.soinside.com 2019 - 2024. All rights reserved.