为什么.append()会影响嵌套列表中的所有元素?
我创建了一个列表的列表,想要往每个小列表里添加东西。但是当我尝试往其中一个小列表里添加元素(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]]
但是为什么会这样呢?这个结果看起来并不直观。我知道这和有多个引用指向同一个列表有关,但我不明白具体是哪里出了问题。
4 个回答
1
2
关键在于这一部分:
a.append(b)
a.append(b)
你在添加同一个列表两次,所以 a[0]
和 a[1]
都指向同一个列表。
在你的第二个例子中,每次你调用 a.append([b])
时,都是在创建新的列表,所以它们是独立的对象,虽然它们的初始值都是相同的浮点数。
39
这是因为列表里存的是对象的引用。你的列表里并不是直接包含 [[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]]