2017-01-23 69 views
0

我一直在Python中使用[Value] * Count表示法来初始化列表。例如,[False] * 3导致创建列表[False, False False]。我尝试使用相同的符号来初始化列表的列表。Python列表中可变对象的ID

>>>a = [[0] * 2] * 3 
>>>print a 
[[0, 0], [0, 0], [0, 0]] 
>>>a[0][1] = 23 
>>>print a 
[[0, 23], [0, 23], [0, 23]] 
>>>id(a[0]) 
139978350226680 
>>>id(a[1]) 
139978350226680 
>>>id(a[2]) 
139978350226680 

正如我们可以看到,一个元素是指一个单独的列表,而不是三次提到三个不同的列表。 1.为什么会发生这种情况? 2.什么是初始化列表清单的正确方法?

同样的行为已经指出了以前的答案:https://stackoverflow.com/a/13382804/4716199

+0

“正确的”方法是使用for循环或列表理解。 –

+0

如果你做了'b = [0] * 2; a = [b] * 3'你会惊讶于'a'包含3个对'b'的引用吗? –

+0

@ PM2Ring这很有道理。我没有意识到*不会创建新的副本,它只是复制参考。感谢:) – Sidhant

回答

1

这就是*经营者名单上的行为:它并没有复印,但份参考。这是有道理的,因为它一般是甚至没有定义如何复制,所以Python只能复制引用,因为它是每个对象的唯一东西。

如果你想建立一个新的列表,你可以使用列表理解:

a = [[0] * 2 for _ in range(3)] 

一般是不是好的做法使用*给出的列表包含可变对象

对于像boolstr这工作,因为你对象本身上不工作不变的对象,但由此产生的阵列上。在你的例子中你使用了链接索引,所以你修改了内部列表。