2017-08-11 103 views
0

我在爲應用多維矩陣的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 

要避免此行爲,必須使用副本。

+0

我不明白是什麼問題。另外,不僅*矩陣中的一個期望的字段發生了變化*意味着什麼? – wallyk

+0

有什麼理由不使用numpy嗎?沒有理由重新發明輪子 – user3080953

+0

@ user3080953我將使用該類來表示評分矩陣,並且性能不是問題。然而,它需要覆蓋一些不同的初始化,所以我認爲最好把它們包裝在一個類中。 – jules

回答

0

你看到的問題是因爲你的矩陣的子陣在內存中實際上是相同的東西,所以修改它會改變它們。

這是你在做什麼:

>>> a = [0, 0] 
>>> m = [a, a] 
>>> m 
[[0, 0], [0, 0]] 
>>> m[0][1] = 42 
>>> m 
[[0, 42], [0, 42]] 
>>> id(m[0]) == id(m[1]) # same object in memory 
True 

這是你想要做什麼:

>>> a = [0,0] 
>>> m = [a.copy(), a.copy()] 
>>> m[0][1] = 42 
>>> m 
[[0, 42], [0, 0]] 
>>> id(m[0]) == id(m[1]) # different objects in memory 
False 

話雖這麼說,這是一個更容易在numpy的做:

>>> import numpy as np 
>>> m = np.zeros((2, 2)) 
>>> m[0,1] = 42 
>>> m 
array([[ 0., 42.], 
     [ 0., 0.]]) 
+0

謝謝你的回答!我猜測它是這樣的,但是當它在shell中工作時我感到非常困惑。 – jules