Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python ijk乘法,为什么我们要使用下面的赋值符号或代码行?_Python_Matrix Multiplication - Fatal编程技术网

Python ijk乘法,为什么我们要使用下面的赋值符号或代码行?

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]

我试图实现两个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
为什么我们在第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]