首页 > 解决方案 > 使用 Python 列表的“附加”时出现意外行为

问题描述

我试图理解python 列表的这种行为。

当我将一个空列表附加到另一个列表时,我希望新列表只包含一个空列表。但我不明白为什么它会添加意想不到的值。

main = [ [1,2,3], [4,5], [6] ]

l1 = []
l2 = []

for i in main:
    
    for j in i:
        l1.append(j)
    
    # reseting value of l1 to empty list
    l1 = []
    
    # expected behaviour: an empty list will be added!
    l2.append(l1)

print(l2)

希望此代码能够打印

> [[], [], []]

但它了我:

> [[4, 5], [6], []]

有人可以解释这是怎么发生的吗?

标签: pythonlist

解决方案


l1 = []并不意味着“清除此列表”。这意味着“创建一个新的空列表并让l1名称引用该列表”。之前提到的任何对象l1都不会被此操作修改。

此外,l2.append(l1)并不意味着“将副本附加l1l2”或“将此变量附加到l2”。它的意思是“将此特定列表附加到l2”。l2接收对原始列表的引用,而不是新列表,并且对原始列表的修改将通过l2. (它接收对列表的引用,而不是对l1变量的引用 - 重新绑定l1到新列表不会影响l2。)


在外部循环的第一次迭代结束时,将一个空列表附加到l2. 然后下一次迭代将一堆东西附加到该列表中,然后重新绑定l1到一个新的空列表,在旧列表中留下一堆元素。同样的情况也发生在外循环的下一次和最后一次迭代中。

如果要清除列表,请使用

l1.clear()

或者

del l1[:]

而不是l1 = [].

此外,如果要创建列表的(浅)副本,可以使用l1[:]. 例如,附加l1to的副本l2

l2.append(l1[:])`

如果您将代码更改为 clear l1,但不将副本附加到l2l2则将包含对单个列表的 3 个引用。这很少是你想要的。


推荐阅读