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

Mat*_*att 4 python nested-lists

我刚刚遇到了一些非常奇怪的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]]
Run Code Online (Sandbox Code Playgroud)

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

[[0, 9, 0], [0, 0, 0], [0, 0, 0]]
Run Code Online (Sandbox Code Playgroud)

不奇怪吗?我对Python不是很熟悉,但Python总是以其直观的行为给我留下深刻的印象.但它是如何产生的呢?
......我怎样才能得到我需要的东西?

谢谢!

And*_*ark 8

使用*复制列表中的元素是一个浅拷贝操作,所以你最终将与相同的可变对象的多个引用如果你使用这个包含可变对象名单.

而是,使用以下内容初始化嵌套列表:

out = [[0]*3 for _ in range(3)]
Run Code Online (Sandbox Code Playgroud)

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

>>> out = [[0]*3]*3
>>> out[0] is out[1] is out[2]
True
Run Code Online (Sandbox Code Playgroud)


Zau*_*bov 7

确实是一种奇怪的行为,但这只是因为*运算符在你的情况下做了浅拷贝 - [0, 0, 0]列表的浅拷贝.您可以使用该id()函数来确保这些内部列表实际上是相同的:

out=[[0]*3]*3
id(out[0])
>>> 140503648365240
id(out[1])
>>> 140503648365240
id(out[2])
>>> 140503648365240
Run Code Online (Sandbox Code Playgroud)

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

out = [ [0]*3 for _ in range(3) ]
Run Code Online (Sandbox Code Playgroud)