我正在尝试实现两个2 * 2矩阵的简单乘法。我遇到了以下代码。
def ikjMatrixProduct(A, B):
n = len(A)
C = [[0 for i in range(n)] for j in range(n)]
for i in range(n):
for k in range(n):
for j in range(n):
C[i][j] += A[i][k] * B[k][j]
return C
我们为什么要使用此分配: C = [第3行中的[[0表示范围(n)中的i,0]表示范围(n)中的j]
我以前从未见过这样的作业。可以请别人解释一下。
我自己的代码抛出错误,因为我使用了c = []并且此代码有效。
答案 0 :(得分:1)
正如Merlin1896所说,C = [[0 for i in range(n)] for j in range(n)]
创建一个2D列表,即n
列表的列表,每个内部列表包含n
零。列表为空,直到您将其填满为止。如果C是一个空列表,则无法执行C[i][j] += A[i][k] * B[k][j]
,因为C[i][j]
还不存在。
一种更快的初始化矩阵的方法是
C = [[0] * n for j in range(n)]
在最里面的列表上使用列表乘法是安全的,因为它们包含不可变的整数。但是在外部列表上不是安全的,因为列表是可变的。进行C = [[0] * n] * n
会使外部列表引用一个列表对象。例如,
n = 4
C = [[0] * n] * n
print(C)
C[0][0] = 1
print(C)
输出
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
[[1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0]]
但是,最好重新组织代码,以免不必用零填充列表。我们可以通过更改循环顺序,使k
循环成为最内部循环来实现。然后,我们可以将内置的sum
函数与生成器表达式一起使用。
def ikjMatrixProduct(A, B):
n = len(A)
C = []
for i in range(n):
row = []
for j in range(n):
row.append(sum(A[i][k] * B[k][j] for k in range(n)))
C.append(row)
return C
我们可以将其转化为列表理解,尽管许多人认为三重嵌套的列表理解/生成器表达式不是很可读。 ;)
def ikjMatrixProduct(A, B):
nrange = range(len(A))
return [[sum(A[i][k] * B[k][j] for k in nrange) for j in nrange] for i in nrange]