以下python代码:
matrix = [[0]*3]*2
matrix[0][1] = 1
似乎要更改所有 matrix[][1]
位置的值,矩阵变为
[[0,1,0],[0,1,0]]
而不是 [[0,1,0],[0,0,0]]
.
这是变量初始化方式的问题还是 python 中的默认行为。
还有如何一次只更改一个值。
最佳答案
乘法运算符 *
在 python 中如何处理列表有一些微妙之处。
更一般地说,当应用于整数或字符串等不可变对象时,它的效果与应用于可变对象(如列表和字典)时的效果不同.
这可能会澄清问题:
>>> l = [0] * 3 #a list of immutable integers
>>> l
[0, 0, 0]
>>> l[0] = 1
>>> l
[1, 0, 0]
>>> l = [[0]] * 3 #a list of mutable lists
>>> l
[[0], [0], [0]]
>>> l[0][0] = 1
>>> l
[[1], [1], [1]]
编辑(在评论中感谢@lazyr) 在这两种情况下,*
操作符创建一个具有相同标识(内存地址)的对象列表,所以数组中的每个数字(和每个列表)实际上都是同一个对象,但是,不可变类型不能修改而只能替换,所以当你试图为整数数组分配一个新值时,你实际上会替换整个对象,而列表不是这种情况。基于前面的示例(请记住 id
函数返回对象的内存地址):
>>> m = [1] * 3
>>> id(m[0])
39356344
>>> id(m[1])
39356344
>>> m[1] = 2
>>> id(m[1])
39356320 # new memory addres = different object!
>>> m = [[1]] * 3
>>> id(m[0])
40275408
>>> id(m[1])
40275408
>>> m[1][0] = 2
>>> id(m[1])
40275408 # same memory address = still the same object!
因此,在您的情况下,可能的解决方法是像这样初始化矩阵:
>>> matrix = [[0 for i in range(3)] for j in range(2)]
>>> matrix
[[0, 0, 0], [0, 0, 0]]
>>> matrix[0][2] = 1
>>> matrix
[[0, 1, 0], [0, 0, 0]]
另一种更激进的方法是完全切换到 numpy ,它速度更快,并且从头开始考虑用于极快的矩阵和多维向量操作,但它也更难使用。
喂!
关于python - 尝试在一个位置更改时,列表列表中多个位置的值发生变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8240054/