Python 使用列表理解乘法矩阵

Python 使用列表理解乘法矩阵,python,Python,有人能帮我理解矩阵乘法的原理吗 def matrix_mul(a, b): return [[sum(i * j for i, j in zip(r, c)) for c in zip(*b)] for r in a] a = [[1, 2], [3, 4]] b = [[5, 1], [2, 1]] c = matrix_mul(a, b) 表达式基本上有三个嵌套的列表理解(尽管实际上其中一个是生成器表达式)。如果将它们替换为显式循环,为正在构建的列表添加一些适当命

有人能帮我理解矩阵乘法的原理吗

def matrix_mul(a, b):
    return [[sum(i * j for i, j in zip(r, c)) for c in zip(*b)]
        for r in a]

a = [[1, 2], [3, 4]]
b = [[5, 1], [2, 1]]
c = matrix_mul(a, b)

表达式基本上有三个嵌套的列表理解(尽管实际上其中一个是生成器表达式)。如果将它们替换为显式循环,为正在构建的列表添加一些适当命名的变量,并添加一些打印语句,则可以看到发生了什么:

def matrix_mul(a, b):

    matrix_out = []
    for r in a:
        print("    Input row of a", r)
        row_out = []
        for c in zip(*b):
            print("        Input column of b", c)

            products = []
            for i, j in zip(r, c):
                print("            Values to multiply:", i, j)
                inputs = i, j
                products.append(i * j)
                
            print("        List of products:", products)
            print("        Sum of products:", sum(products))
            row_out.append(sum(products))
            
        matrix_out.append(row_out)
        print("    Row of answer", row_out)
        print()
    print("Answer", matrix_out)
    return matrix_out


a = [[1, 2], [3, 4]]
b = [[5, 1], [2, 1]]
c = matrix_mul(a, b)
给出:

    Input row of a [1, 2]
        Input column of b (5, 2)
            Values to multiply: 1 5
            Values to multiply: 2 2
        List of products: [5, 4]
        Sum of products: 9
        Input column of b (1, 1)
            Values to multiply: 1 1
            Values to multiply: 2 1
        List of products: [1, 2]
        Sum of products: 3
    Row of answer [9, 3]

    Input row of a [3, 4]
        Input column of b (5, 2)
            Values to multiply: 3 5
            Values to multiply: 4 2
        List of products: [15, 8]
        Sum of products: 23
        Input column of b (1, 1)
            Values to multiply: 3 1
            Values to multiply: 4 1
        List of products: [3, 4]
        Sum of products: 7
    Row of answer [23, 7]

Answer [[9, 3], [23, 7]]
使用示例值解释
zip(*b)

b = [[5, 1], [2, 1]]
*
将使其将顶级列表扩展为多个单独的参数

zip([5, 1], [2, 1])
然后zip将产生一个元组序列,由每个输入列表的第一个元素组成,然后是每个输入列表的第二个元素(依此类推,尽管在本例中只有两对),即

换句话说,
b
的列



(注意:由于原始代码中对
sum
的输入实际上是一个生成器表达式,而不是列表理解,因此它实际上并不生成产品列表,而是生成一系列产品,这些产品由
sum
函数一次一个地消耗。但这样做除了提高效率之外,效果基本相同。)

您的表达式基本上有三个嵌套的列表理解(尽管事实上其中一个是生成器表达式)。如果将它们替换为显式循环,为正在构建的列表添加一些适当命名的变量,并添加一些打印语句,则可以看到发生了什么:

def matrix_mul(a, b):

    matrix_out = []
    for r in a:
        print("    Input row of a", r)
        row_out = []
        for c in zip(*b):
            print("        Input column of b", c)

            products = []
            for i, j in zip(r, c):
                print("            Values to multiply:", i, j)
                inputs = i, j
                products.append(i * j)
                
            print("        List of products:", products)
            print("        Sum of products:", sum(products))
            row_out.append(sum(products))
            
        matrix_out.append(row_out)
        print("    Row of answer", row_out)
        print()
    print("Answer", matrix_out)
    return matrix_out


a = [[1, 2], [3, 4]]
b = [[5, 1], [2, 1]]
c = matrix_mul(a, b)
给出:

    Input row of a [1, 2]
        Input column of b (5, 2)
            Values to multiply: 1 5
            Values to multiply: 2 2
        List of products: [5, 4]
        Sum of products: 9
        Input column of b (1, 1)
            Values to multiply: 1 1
            Values to multiply: 2 1
        List of products: [1, 2]
        Sum of products: 3
    Row of answer [9, 3]

    Input row of a [3, 4]
        Input column of b (5, 2)
            Values to multiply: 3 5
            Values to multiply: 4 2
        List of products: [15, 8]
        Sum of products: 23
        Input column of b (1, 1)
            Values to multiply: 3 1
            Values to multiply: 4 1
        List of products: [3, 4]
        Sum of products: 7
    Row of answer [23, 7]

Answer [[9, 3], [23, 7]]
使用示例值解释
zip(*b)

b = [[5, 1], [2, 1]]
*
将使其将顶级列表扩展为多个单独的参数

zip([5, 1], [2, 1])
然后zip将产生一个元组序列,由每个输入列表的第一个元素组成,然后是每个输入列表的第二个元素(依此类推,尽管在本例中只有两对),即

换句话说,
b
的列


(注意:由于原始代码中对
sum
的输入实际上是一个生成器表达式,而不是列表理解,因此它实际上并不生成产品列表,而是生成一系列产品,这些产品由
sum
函数一次一个地消耗。但这样做除了提高效率之外,效果基本相同。)

因此,通过贴花:

def矩阵(a,b):

你实际上正在做以下工作:

a = [[1, 2], [3, 4]]
b = [[5, 1], [2, 1]]
数组B(5)的第一个元素乘以数组A(1)的第一个元素)+数组A(2)的snd元素乘以数组B[1](2)的第一个元素。因此,要获得c u,需要执行以下操作:

c = [[9,3],[23,7]]
9 = a[0][0] * b[0][0] + a[0][1] * b[1][0]
3 = a[0][0] * b[0][1] + a[0][1] * b[1][1]
23 = a[1][0] * b[0][0] + a[1][1] * b[1][0]
7 = a[1][0] * b[1][0] + a[1][1] * b[1][1]
我认为这是正确的asnwer。希望我通过贴花帮助您:

def矩阵(a,b):

你实际上正在做以下工作:

a = [[1, 2], [3, 4]]
b = [[5, 1], [2, 1]]
数组B(5)的第一个元素乘以数组A(1)的第一个元素)+数组A(2)的snd元素乘以数组B[1](2)的第一个元素。因此,要获得c u,需要执行以下操作:

c = [[9,3],[23,7]]
9 = a[0][0] * b[0][0] + a[0][1] * b[1][0]
3 = a[0][0] * b[0][1] + a[0][1] * b[1][1]
23 = a[1][0] * b[0][0] + a[1][1] * b[1][0]
7 = a[1][0] * b[1][0] + a[1][1] * b[1][1]

我认为这是正确的asnwer。希望我能帮助您理解列表,它只是一个简短的for循环语法,将元素附加到一个新的列表中。我建议您将其分解为一个常规的for循环,并检查和打印每个表达式的作用。我建议更改输入,使每个元素都是唯一的,更易于遵循低,例如:
b=[[5,6],[7,8]
列表理解只是for循环的一种较短语法,它将元素附加到新列表中。我建议您将其分解为常规for循环,并检查和打印每个表达式的功能。我建议更改输入,使每个元素都是唯一的,并且更易于理解,例如:
b=[[5,6],[7,8]]
OP,这是一个很好的答案!这正是我在写评论时想到的。试着看看这一点,看看你自己是如何达到这个结果的,这将对你以后理解复杂代码有很大帮助。@Adam.Er8谢谢你的评论。我添加了一个关于
zip(*b)的解释
因为即使在使用显式循环时,这可能也不会立即变得明显,但我认为,一旦将列表理解解压为显式循环,所有其他内容都是不言而喻的。感谢alanwi的详细解释,它确实帮助我理解了codeOP,这是一个极好的答案!正是我所想的当然,在写我的评论时。试着看看这一点,看看你自己是如何达到这个结果的,这将对你以后理解复杂代码有很大帮助。@Adam.Er8谢谢你的评论。我添加了对
zip(*b)的解释
因为即使在使用显式循环时,这一点也不太明显,但我认为,一旦将列表理解解压为显式循环,其余的内容都是不言而喻的。感谢alanwi的详细解释,它确实帮助我理解了代码