Python ijk乘法,为什么我们要使用下面的赋值符号或代码行?
我试图实现两个2*2矩阵的简单乘法。我遇到了以下代码Python ijk乘法,为什么我们要使用下面的赋值符号或代码行?,python,matrix-multiplication,Python,Matrix Multiplication,我试图实现两个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]
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
为什么我们在第3行中使用这个赋值:C=[[0表示范围(n)中的i]表示范围(n)中的j]
我以前从来没有看过那个作业。请有人解释一下
我自己的代码抛出了一个错误,因为我使用了c=[],这段代码运行正常。正如Merlin1896所说,
c=[[0代表范围内的i(n)]代表范围内的j(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
我们可以将其转换为列表理解,尽管许多人认为三重嵌套的列表理解/生成器表达式不太可读。(
行
C=[[0表示范围(n)中的i]表示范围(n)中的j]
创建了一个用零填充的n×n矩阵。这是需要的,因为在C[i][j]+=A[i][k]*B[k][j]
行中可以访问C
的元素。如果矩阵没有被初始化,您将在这里得到一个错误。顺便说一句:请看一下numpy
,然后再看一遍你的代码。另一种方法是np.zeros((n,n))
还要注意,为了使用python列表初始化零矩阵,您确实需要某种双循环。有人可能会认为,使用列表乘法创建2x2嵌套列表是可以的,但如果这样做,则两行的同一列表可能会有多个引用,然后对矩阵中的某个项进行变异也会更改其他项。看看我的意思。@Merlin1896,W Stokvis:我们的教授希望我们不使用任何库来编写代码。因此我没有使用numpy。Andras Deak,这个例子很有帮助!顺便说一句,当创建多维列表时,当项目不可变时,在最里面的列表上使用列表乘法是安全的。所以你可以这样做,例如,C=[[0]*n代表范围(n)]内的j
。这比双Python循环快一点,因为[0]*n
是以C速度完成的。感谢您的解释。我特别喜欢三重嵌套列表理解的最后一个示例!我有一个关于这个代码的问题。n=4 C=[[0]*n]*n打印(C)。这将输出[0,0,0,0]的4*1列表。我不明白下面的部分,我们已经说过C[0][0]=1,但是第二行还不存在。那么为什么代码没有抛出错误呢?还有,我们如何得到第二行的[1,0,0,0]??C[0][0]=1打印(C)请忽略前面的评论。我将我的问题重新定义如下:我有一个关于此代码的问题。n=4;C=[[0]*n]*n;印刷品(C);。这将输出[0,0,0,0]的四个4*1列表。我不明白下面的部分,我们已经说过C[0][0]=1,“1”是如何被广播到整行的,我们得到所有四个4*1列表的[1,0,0,0]输出的?C[0][0]是否表示第一个列表的第一个元素??C[0][0]=1;print(C)。@pi2018在该代码中,C
包含对单个列表对象的4个引用。它不包含4个不同的列表。所以C[0]
、C[1]
、C[2]
和C[3]
只是同一个列表的不同名称。
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]