2016-05-24 45 views
1

我正試圖用簡單的Python操作來實現矩陣類(沒有numpy等)。如何實現對所有子矩陣元素的添加?

這裏是其中的一部分:

class Matrix(list): 
    def __getitem__(self, item): 
     try: 
      return list.__getitem__(self, item) 
     except TypeError: 
      rows, cols = item 
      return [row[cols] for row in self[rows]] 

它允許做這樣的事情:

m = Matrix([[i+j for j in [0,1,2,3]] for i in [0,4,8,12]]) 
print(m[0:2, 0:2]) 
will print: [[0, 1], [4, 5]] 

我也希望能夠通過給定值增加/乘法子矩陣元素,如:

m[0:2, 0:2] += 1 
print(m[0:2, 0:2]) 
should print: [[1, 2], [5, 6]] 

目前尚不清楚應該採用哪種神奇方法才能使其發揮作用?

回答

1

首先,從list繼承是一個壞的舉動。矩陣不支持列表所做的操作類型;例如,您不能將appendextend作爲矩陣,並且項目分配完全不同。你的矩陣應該包含一個列表,而不是一個列表。

至於你需要什麼神奇的方法,m[0:2, 0:2] += 1大致翻譯如下:

temp = m.__getitem__((slice(0, 2), slice(0, 2))) 
temp = operator.iadd(temp, 1) 
m.__setitem__((slice(0, 2), slice(0, 2)), temp) 

其中operator.iadd嘗試temp.__iadd__temp.__add__,並(1).__radd__執行加法。

您需要執行__getitem____setitem__來檢索子矩陣並分配新的子矩陣。此外,__getitem__將需要返回一個矩陣,而不是一個列表。

你應該實現__add____iadd__;而__add__本身就足夠用於這種情況,__iadd__將需要像m += 1這樣的操作就地工作,而不是用新的矩陣對象替換m

+0

好吧,也許你可以分享一些代碼。因爲對於所有我想要的東西,我甚至在魔法方法出現之前就得到了'TypeError' –

0

__iadd__會做的伎倆你,如果魔術隊:

m += 2 

但在m[0:2, 0:2]執行魔術。您需要確保在對矩陣進行切片時得到不同的對象,而不是列表列表,因爲列表列表不支持__iadd__