寫一個函數,接收兩個由嵌套列表模擬成的矩陣,返回一個嵌套列表作為計算結果,要求運行效果如下:
>>> matrix1 = [[1, 1], [-3, 4]]
>>> matrix2 = [[2, -1], [0, -5]]
>>> add(matrix1, matrix2)
[[3, 0], [-3, -1]]
>>> matrix1 = [[1, -2, 3], [-4, 5, 6], [7, -8, 9]]
>>> matrix2 = [[1, 1, 0], [1, -2, 3], [-2, 2, -2]]
>>> add(matrix1, matrix2)
[[2, -1, 3], [-3, 3, 9], [5, -6, 7]]
最初思路是這樣的:
嵌套循環遍歷矩陣1的數據,通過index方法獲得行索引和列索引(這里大錯特錯了),利用索引來取得矩陣2的相同位置的數據,再進行加法。
由於忽略了index方法只能找到第一個值的索引,導致當矩陣中有重復元素時,會一直用重復元素中的第一個進行計算。
正確的做法:
直接按照索引遍歷,再用多個下標操作符去取得元素的值。
def add(matrix1, matrix2): result = [] for row in range(len(matrix1)): # 行索引 row_result = [] for column in range(len(matrix1[row])): # 列索引 row_result.append(matrix1[row][column]+matrix2[row][column]) # 行結果 result.append(row_result) # 矩陣結果 return result
這樣寫,只能計算兩個矩陣的加法,我們需要進一步擴展這個函數的功能,比如,讓它可以計算任意多個矩陣的加法
只需要改成動態參數,每個位置的結果根據矩陣個數進行相應次數的計算。主體思路不變,仍然是以第一個矩陣的索引為准,取得其他矩陣對應位置的數據相加。
def add(*args): result = [] num = len(args) # 獲得矩陣個數,方便后面的計算 for row in range(len(args[0])): row_result = [] for column in range(len(args[0][row])): value_result = args[0][row][column] # 存儲單個數據計算結果 for x in range(num - 1): # 進行(矩陣數-1)次加法 value_result += args[x + 1][row][column] row_result.append(value_result) result.append(row_result) return result
這時,我們還想再完善一下這個函數,矩陣加法要求矩陣的行列數必須保持一致,我們就讓它能夠檢測傳入的矩陣的一致性,並拋出異常
ValueError:Given matrices are not the same size.
再進行計算之前,先檢測合法性,遍歷查看后續矩陣的行列數是否和第一個矩陣相同。
這里,使用filter以數據長度為條件進行篩選,若有被篩出去的數據,就說明矩陣大小不一致。
def add(*args): result = [] num = len(args) # 獲得矩陣個數,方便后面的計算 row_num = len(args[0]) column_num = len(args[0][0]) # 獲得矩陣1的行列數,用於檢測參與計算的矩陣的一致性 try: # 檢測行數是否一致,若有被篩出去的矩陣,說明不一致 if len(list(filter(lambda r: len(r) == row_num, args))) != num: raise ValueError('Given matrices are not the same size.') for x in range(num): # # 檢測列數是否一致,若有被篩出去的行,說明不一致 if len(list(filter(lambda r: len(r) == column_num, args[x]))) != row_num: raise ValueError('Given matrices are not the same size.') for row in range(len(args[0])): row_result = [] for column in range(len(args[0][row])): value_result = args[0][row][column] # 存儲單個數據計算結果 for x in range(num - 1): # 進行(矩陣數-1)次加法 value_result += args[x + 1][row][column] row_result.append(value_result) result.append(row_result) return result except ValueError: raise