我有以下代码:
matrix = [[0] * 3] * 3
matrix[0][0] = 2
我想得到以下结果:
[[2, 0, 0], [0, 0, 0], [0, 0, 0]]
然而,它会更改每个子列表的第一个元素并返回此列表:
[[2, 0, 0], [2, 0, 0], [2, 0, 0]]
如果我将矩阵定义如下:
matrix = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
然后它有效。
有人能告诉我,为什么会这样,怎么能解决这个问题?
由于
答案 0 :(得分:1)
这种情况正在发生,因为[[0] * 3] * 3
实际上是在创建一个由3个相同对象([0] * 3
数组)组成的数组。查看它的一种方法是内部数组创建一次并复制。另一种方法是使用[[0] * 3 for x in xrange(3)]
,因为这会在列表推导中每次迭代执行[0] * 3
,每次都会创建一个新数组。
答案 1 :(得分:0)
Python通过指针而不是值*来分配,这有时会导致不良结果,例如这个。这是一个解释实际情况的教程:http://www.python-course.eu/variables.php这是一个可能的解决方法http://www.python-course.eu/deep_copy.php
*(正如已经指出的那样,这是不太正确的,但它与其他语言如C的情况类似,如果您传递一个指向变量的指针而不是一个副本,我会更熟悉它变量的值。)
答案 2 :(得分:0)
这是您的问题,在此示例中,matrix
基本上与:
>>> a = [0,0,0]
>>> matrix1 = [a,a,a]
这意味着当你执行matrix1[0][0] = 2
时,Python所做的是跟随位于matrix1
的第一个索引处的指针,该指针指向对象a
,然后查看位于a
的第一个索引,读取0
,然后将其更改为2
。然后,当您要求它评估matrix1
时,它会查找a
三次,每次都会找到[2,0,0]
。
Sean上面有一个good solution,使用列表推导来强制新对象,而不是为已经存在的对象添加指针。这可能会对你有所帮助:)