我刚刚遇到了一些非常奇怪的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 :(得分:8)
使用*
复制列表中的元素是一个浅层复制操作,因此如果在包含可变对象的列表上使用它,最终会对同一个可变对象进行多次引用。
而是使用以下内容初始化嵌套列表:
out = [[0]*3 for _ in range(3)]
您可以看到,使用您的方法,out
中的每个条目实际上都是对同一列表的引用,这就是您看到行为的原因:
>>> out = [[0]*3]*3
>>> out[0] is out[1] is out[2]
True
答案 1 :(得分:7)
确实是一种奇怪的行为,但这仅仅是因为*
运算符在您的情况下生成浅拷贝 - [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) ]