为什么我不能在 Python 中只更改嵌套列表中的单个元素 [duplicate]

why can't I change only a single element in a nested list in Python [duplicate]

提问人:Matt 提问时间:6/8/2012 更新时间:7/25/2017 访问量:1989

问:

我刚刚遇到了一些非常奇怪的 Python 东西:

>>> out=[[0]*3]*3
>>> out
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> out[0][1]
0
>>> out[0][1]=9
>>> out
[[0, 9, 0], [0, 9, 0], [0, 9, 0]]

好吧,显然,我想要的是:

[[0, 9, 0], [0, 0, 0], [0, 0, 0]]

是不是很奇怪?我对 Python 不是很熟悉,但 Python 的直观行为总是给我留下深刻印象。但是它是怎么想出来的呢?
......我怎样才能得到我需要的东西?

谢谢!

瓦特

嵌套列表

评论

0赞 Mark Ransom 6/8/2012
你在一件事上是对的——它不是很直观。我也不认为他们在 Python 3 中修复了它。

答:

8赞 Andrew Clark 6/8/2012 #1

用于复制列表中的元素是一种浅层复制操作,因此,如果在包含可变对象的列表中使用它,则最终将获得对相同可变对象的多个引用。*

相反,请使用以下命令来初始化嵌套列表:

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

您可以看到,使用您的方法,每个条目实际上是对同一列表的引用,这就是您看到您所做的行为的原因:out

>>> out = [[0]*3]*3
>>> out[0] is out[1] is out[2]
True
9赞 Zaur Nasibov 6/8/2012 #2

这确实是一种奇怪的行为,但这只是因为操作员制作了浅副本,在您的情况下 - 列表的浅副本。您可以使用该函数来确保这些内部列表实际上是相同的:*[0, 0, 0]id()

out=[[0]*3]*3
id(out[0])
>>> 140503648365240
id(out[1])
>>> 140503648365240
id(out[2])
>>> 140503648365240

推导可用于创建不同的列表,如下所示:

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