我有以下问题:
我有一份列表清单,其中包含以下声明:
As = [[0]*3]*3
然后我尝试用这个改变这个“矩阵”的值:
for i in range(3):
for j in range(3):
As[i][j] = calculate(A, i, j)*((-1)**(i+j))
您可能已经猜到,这用于计算3x3矩阵的逆矩阵。
函数calculate返回以下值:
4.0
-2.0
-3.0
-4.0
-10.0
9.0
4.0
10.0
-21.0
但是,As具有以下值:
[[4.0, -10.0, -21.0], [4.0, -10.0, -21.0], [4.0, -10.0, -21.0]]
,这是意外的。
我错过了什么?
答案 0 :(得分:2)
当您构建类似此[[0]*3]*3
的列表时,您创建了3个对同一列表的引用,请改为使用列表推导:
[[0 for _ in xrange(3)] for _ in xrange(3)]
在这里理解如何修改[0][0]
:
>>> l1 = [[0]*3]*3
>>> l1[0][0] = 10
>>> l1
[[10, 0, 0], [10, 0, 0], [10, 0, 0]]
>>> l2 = [[0 for _ in xrange(3)] for _ in xrange(3)]
>>> l2[0][0] = 10
>>> l2
[[10, 0, 0], [0, 0, 0], [0, 0, 0]]
答案 1 :(得分:1)
问题出在第一行:
As = [[0]*3]*3
这相当于以下内容:
a = [0] * 3
As = [a] * 3
因此, As
包含对同一列表的三个引用:
>>> for a in As:
... print(id(a))
...
4293437996
4293437996
4293437996
因此,当您更改此列表时,它会反映在矩阵的所有行中。
要解决此问题,您可以使用列表推导来构建外部列表:
As = [[0] * 3 for _ in xrange(3)]
请注意,内部列表[0] * 3
没问题,因为列表只包含一个不可变的整数。因此,列表引用该整数的相同实例并不重要,因为它们无法更改。