我在为应用多维矩阵的Matrix类编写setter函数时遇到了麻烦,因为我没有实现动态编程算法。插入到未知维度的矩阵
矩阵使用嵌套列表进行存储。由于维度是未知的,代码背后的想法是使用坐标(索引列表)并在从坐标读取索引时迭代地进入矩阵。
def setField(self, coordinate, value):
coordinate = coordinate[::-1] # reverse the coordinate so .pop() can be used
field = self.matrix
while len(coordinate) > 1:
field = field[coordinate.pop()]
field[coordinate[0]] = value
使用代码:
>>> m = Matrix([3,3,3]) # initialize Matrix of size 3 in all dimensions
>>> m.tolist() # list representation
[[[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]
>>> m.setField([1,1,1], 42) # at position [1,1,1] insert 42
>>> m.tolist()
[[[0, 0, 42], [0, 0, 42], [0, 0, 42]], [[0, 0, 42], [0, 0, 42], [0, 0, 42]], [[0, 0, 42], [0, 0, 42], [0, 0, 42]]]
现在麻烦的是,该“步入矩阵”部分与该矩阵的引用来完成。由于我不明白的原因,这种改变不仅发生在一个领域(矩阵应该改变为给定值),而是发生在矩阵表示的每个子列表中。
什么让我困惑甚至更多,是下面的代码工作得很好,在Python外壳:
>>> m = [[0,0],[0,0]]
>>> field = m
>>> field = field[0]
>>> field[1] = 1
>>> m
[[0, 1], [0, 0]]
- 我在做什么错在这里?
- 为什么Python的行为如此?
编辑/解释
正如指出作为一个答案,在矩阵中的所有子表实际上是相同的。
>>> m = Matrix([2,2])
>>> id(m.matrix[0]) == id(m.matrix[1])
True
要避免此行为,必须使用副本。
我不明白是什么问题。另外,不仅*矩阵中的一个期望的字段发生了变化*意味着什么? – wallyk
有什么理由不使用numpy吗?没有理由重新发明轮子 – user3080953
@ user3080953我将使用该类来表示评分矩阵,并且性能不是问题。然而,它需要覆盖一些不同的初始化,所以我认为最好把它们包装在一个类中。 – jules