我正在尝试更改Python列表中的元素。按照https://www.programiz.com/python-programming/matrix上的教程,我想出了下面的代码。
matrix = [[0]*6]*3
print(matrix)
matrix[0][0] = 2
print(matrix)
运行代码后,我收到以下输出:
[[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]
[[2, 0, 0, 0, 0, 0], [2, 0, 0, 0, 0, 0], [2, 0, 0, 0, 0, 0]]
注意输出的最后一行,每个子列表的第一个元素如何设置为2
。如何进行设置,以便只更改第一个列表的第一个元素。
答案 0 :(得分:3)
这是一个经典的python gotcha,它与所有python对象都是引用的事实有关。在您的情况下,这意味着matrix[0] is matrix[1] is matrix[2]
is
,因为True
是matrix = [[0]*6 for _ in range(3)]
,如果两个对象在内存中是相同的。
改为
matrix[0] is matrix[1] is matrix[2]
现在False
会返回c1
。
或者,使用numpy
来处理没有这些问题的数值数组。
答案 1 :(得分:0)
这是因为矩阵中的每一行都不是一个单独的数组,而是对同一数组的引用。
以下内容将打印出每行的内存位置:
for row in matrix:
print(id(row))
请注意它们都是一样的。这是因为python中的列表是通过引用传递的,而不是复制每个单独的值。
您在代码的第二部分中实际执行的操作是:
row = [0] * 6
matrix = [row, row, row]
你可能会对这样的事情感觉更好:
matrix = [[0 for _ in range(6)] for _ in range(3)]
matrix[0][0] = 2
[[2, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]
为矩阵中创建的每一行创建一个新的数组0
。