在for循环中修改的附加变量未按预期工作

时间:2018-12-25 01:30:40

标签: python list

我有此代码:

lst = []
given = [1, 2, 3, 4, 5]
result = []

for item in given:
    lst.append(item)
    print(lst)
    result.append(lst)

print(result)

我的预期结果是[[1], [1, 2], [1, 2, 3], ...],但是显示的结果是[[1, 2, 3, 4, 5], ...],其中12345重复了5次。怎么了?

lst的打印符合预期,第一循环为[1],第二循环为[1, 2],依此类推。

4 个答案:

答案 0 :(得分:3)

每次将{追加到lst时,Python不会创建result的副本,它只是插入引用。结果,您获得具有N个对同一列表的引用的列表。

要创建lst的副本,可以使用lst.copy()。列表分片运算符的工作方式也同样lst[:]

代码的简化版:

given = [1, 2, 3, 4, 5]
result = [given[0 : i + 1] for i in range(len(given))]
print(result)

结果:

[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5]]

答案 1 :(得分:1)

问题是您要像这样附加列表,这等效于将引用对象附加到原始列表。因此,无论何时修改原始列表,更改都会反映在创建引用的位置,在本例中为BigInteger。在继续通过for循环进行迭代时,附加在result中的所有引用都将不断更新为result的最新值。最终结果是,在for循环的末尾,您将5个引用附加到原始列表lst上,并且所有引用都存储了lst的最新值,即lst

有几种方法可以避免这种情况。您只需要复制值。其中之一是使用[1,2,3,4,5]。另一种方法是使用lst[:]

lst.copy()

答案 2 :(得分:1)

列表是一种可变的数据类型,列表中内存中只有一个副本,除非您将其显式copy显式地复制到另一个变量。所以

result.append(lst)

只需附加真实副本的引用,所有引用均指向同一副本。

最后,您应该了解python中的可变/不可变数据类型和引用计数。

答案 3 :(得分:0)

追加lst.copy()可以得到正确的输出。

lst = []
given = [1,2,3,4,5]
result = []

for item in given:
    lst.append(item)
    print(lst)
    result.append(lst.copy())

print(result)