Python Matrix Multiplication — 3 Methods
Nested loops, list comprehension, and NumPy.dot() — three ways to multiply matrices in Python with working code examples.
What Is Matrix Multiplication?
A matrix is a 2D data structure where numbers are arranged into rows and columns. Python has no built-in matrix type — nested lists represent matrices.
The matrix product (dot product) of matrices A and B computes:
result[i][j] = sum(A[i][k] * B[k][j] for all k)
Example: A = [[1,2],[3,4]], B = [[1,3],[2,5]]
Result = [[5,13],[11,29]]
Requirement: columns of A must equal rows of B. An (m×n) matrix times an (n×p) matrix gives an (m×p) result.
Approach 1: Nested Loops
The most explicit approach — three nested loops iterate over every element combination:
def Multiply(A, B):
result = [[0,0,0], [0,0,0], [0,0,0]]
for i in range(len(A)):
for j in range(len(B[0])):
for k in range(len(B)):
result[i][j] += A[i][k] * B[k][j]
for p in result:
print(p)
return 0
A = [[1, 2, 3], [6, 7, 4], [8, 10, 11]]
B = [[1, 5, 3], [2, 6, 5], [7, 4, 9]]
print("Result:")
Multiply(A, B)
# Output:
# Result:
# [26, 29, 40]
# [48, 88, 89]
# [105, 144, 173]
Approach 2: List Comprehension
More concise — compresses the three loops into a single expression using zip and sum:
def Multiply(X, Y):
result = [[sum(a*b for a,b in zip(X_row, Y_col))
for Y_col in zip(*Y)]
for X_row in X]
for k in result:
print(k)
return 0
A = [[6, 7, 2], [3, 5, 4], [1, 2, 3]]
B = [[1, 5], [2, 5], [6, 3]]
print("Result:")
Multiply(A, B)
# Output:
# Result:
# [32, 71]
# [37, 52]
# [23, 24]
zip(*Y) transposes B — turning columns into rows so zip(X_row, Y_col) pairs matching elements.
sum(a*b ...) computes the dot product for each output cell.
Approach 3: NumPy
For any production or numerical computing use, NumPy's dot() is the right tool — implemented in optimized C/Fortran (BLAS), orders of magnitude faster than pure Python loops. It's worth internalizing: every neural network forward pass — from CNN convolutions to transformer attention — reduces to exactly this operation, executed billions of times:
import numpy as np
A = [[12, 7, 3], [4, 5, 6], [7, 8, 9]]
B = [[5, 8, 1, 2], [6, 7, 3, 0], [4, 5, 9, 1]]
result = np.dot(A, B) # or: A @ B (Python 3.5+)
for p in result:
print(p)
# Output:
# [114 160 60 27]
# [ 74 97 73 14]
# [119 157 112 23]
Comparison
- Nested loops: most explicit, easiest to understand, slowest (pure Python overhead)
- List comprehension: concise, Pythonic, still pure Python — not suitable for large matrices
- NumPy dot(): fastest by orders of magnitude, handles any shape, industry standard — use for anything beyond learning exercises