我创建了一个列表列表,并希望将项目附加到各个列表,但是当我尝试附加到其中一个列表(a[0].append(2)
)时,该项目将添加到所有列表中。
a = []
b = [1]
a.append(b)
a.append(b)
a[0].append(2)
a[1].append(3)
print(a)
给予:[[1, 2, 3], [1, 2, 3]]
我希望:[[1, 2], [1, 3]]
更改构建初始列表列表的方式,使b
成为浮点而不是列表并将括号放在.append()
中,为我提供了所需的输出:
a = []
b = 1
a.append([b])
a.append([b])
a[0].append(2)
a[1].append(3)
print(a)
给予:[[1, 2], [1, 3]]
但为什么呢?结果应该不同是不直观的。我知道这与multiple references to the same list有关,但我不知道发生了什么。
答案 0 :(得分:23)
这是因为列表包含对象的引用。您的列表不包含[[1 2 3] [1 2 3]]
,它是[<reference to b> <reference to b>]
。
当您更改对象时(通过向b
添加内容),您将更改对象本身,而不是包含该对象的列表。
要获得所需效果,您的列表a
必须包含b
的副本,而不是b
的引用。要复制列表,您可以使用范围[:]
。例如,:
>>> a=[]
>>> b=[1]
>>> a.append(b[:])
>>> a.append(b[:])
>>> a[0].append(2)
>>> a[1].append(3)
>>> print a
[[1, 2], [1, 3]]
答案 1 :(得分:2)
关键是这一部分:
a.append(b)
a.append(b)
您要将相同的列表追加两次,因此a[0]
和a[1]
都是对同一列表的引用。
在第二个示例中,每次调用像a.append([b])
这样的追加时,都会创建新列表,因此它们是使用相同浮点值初始化的单独对象。
答案 2 :(得分:1)
为了制作列表的浅表副本,这个成语是
a.append(b[:])
当加倍时会导致a有两个新的列表b
的副本,这些副本不会给你报告的别名错误。