5

我刚刚遇到了一些非常奇怪的 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 总是以其直观的行为给我留下深刻印象。但它是怎么想出来的呢?
...我怎样才能得到我需要的东西?

谢谢!

4

2 回答 2

9

确实是一种奇怪的行为,但这只是因为*操作员制作了浅表副本,在您的情况下 -[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) ]
于 2012-06-07T23:07:35.063 回答
8

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

相反,请使用以下内容来初始化您的嵌套列表:

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

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

>>> out = [[0]*3]*3
>>> out[0] is out[1] is out[2]
True
于 2012-06-07T23:05:11.053 回答