在Python中初始化矩阵
有许多方法可以声明具有给定行数和列数的二维数组。让我们看看其中的一些,以及随之而来的小而棘手的捕获。
我们可以使用列表推导、*运算符的连接功能和其他一些方法来做到这一点。
方法 0:2 列表推导
Python3
rows = 3
cols = 2
mat = [[0 for _ in range(cols)] for _ in range(rows)]
print(f'matrix of dimension {rows} x {cols} is {mat}')
# editing the individual elements
mat[0][0], mat[0][1] = 1,2
mat[1][0], mat[1][1] = 3,4
mat[2][0], mat[2][1] = 5,6
print(f'modified matrix is {mat}')
# checking the memory address of first element of a row
print(f'addr(mat[0][0]) = {id(mat[0][0])}, addr(mat[0][1]) = {id(mat[0][1])}')
print(f'addr(mat[1][0]) = {id(mat[1][0])}, addr(mat[1][1]) = {id(mat[1][1])}')
print(f'addr(mat[2][0]) = {id(mat[2][0])}, addr(mat[2][1]) = {id(mat[2][1])}')
Python3
rows = 3
cols = 2
mat = [[0 for _ in range(cols)]]*rows
print(f'matrix with dimension {rows} x {cols} is {mat}')
# editing the individual elements
mat[0][0], mat[0][1] = 1,2
mat[1][0], mat[1][1] = 3,4
mat[2][0], mat[2][1] = 5,6
print(f'modified matrix is {mat}')
# checking the memory address of first element of a row
print(f'addr(mat[0][0]) = {id(mat[0][0])}, addr(mat[0][1]) = {id(mat[0][1])}')
print(f'addr(mat[1][0]) = {id(mat[1][0])}, addr(mat[1][1]) = {id(mat[1][1])}')
print(f'addr(mat[2][0]) = {id(mat[2][0])}, addr(mat[2][1]) = {id(mat[2][1])}')
Python3
rows = 3
cols = 2
mat = [[0]*cols for _ in range(rows)]
print(f'matrix with dimension {rows} x {cols} is {mat}')
# editing the individual elements
mat[0][0], mat[0][1] = 1,2
mat[1][0], mat[1][1] = 3,4
mat[2][0], mat[2][1] = 5,6
print(f'modified matrix is {mat}')
# checking the memory address of first element of a row
print(f'addr(mat[0][0]) = {id(mat[0][0])}, addr(mat[0][1]) = {id(mat[0][1])}')
print(f'addr(mat[1][0]) = {id(mat[1][0])}, addr(mat[1][1]) = {id(mat[1][1])}')
print(f'addr(mat[2][0]) = {id(mat[2][0])}, addr(mat[2][1]) = {id(mat[2][1])}')
Python3
rows = 3
cols = 2
mat = [[0]*cols]*rows
print(f'matrix with dimension {rows} x {cols} is {mat}')
# editing the individual elements
mat[0][0], mat[0][1] = 1,2
mat[1][0], mat[1][1] = 3,4
mat[2][0], mat[2][1] = 5,6
print(f'modified matrix is {mat}')
# checking the memory address of first element of a row
print(f'addr(mat[0][0]) = {id(mat[0][0])}, addr(mat[0][1]) = {id(mat[0][1])}')
print(f'addr(mat[1][0]) = {id(mat[1][0])}, addr(mat[1][1]) = {id(mat[1][1])}')
print(f'addr(mat[2][0]) = {id(mat[2][0])}, addr(mat[2][1]) = {id(mat[2][1])}')
Python3
import numpy as np
rows = 3
cols = 2
size = rows*cols
mat = np.array([0]*size).reshape(rows,cols)
输出
matrix of dimension 3 x 2 is [[0, 0], [0, 0], [0, 0]]
modified matrix is [[1, 2], [3, 4], [5, 6]]
addr(mat[0][0]) = 11094304, addr(mat[0][1]) = 11094336
addr(mat[1][0]) = 11094368, addr(mat[1][1]) = 11094400
addr(mat[2][0]) = 11094432, addr(mat[2][1]) = 11094464
方法一:内部1个列表推导,外部1个串联操作
Python3
rows = 3
cols = 2
mat = [[0 for _ in range(cols)]]*rows
print(f'matrix with dimension {rows} x {cols} is {mat}')
# editing the individual elements
mat[0][0], mat[0][1] = 1,2
mat[1][0], mat[1][1] = 3,4
mat[2][0], mat[2][1] = 5,6
print(f'modified matrix is {mat}')
# checking the memory address of first element of a row
print(f'addr(mat[0][0]) = {id(mat[0][0])}, addr(mat[0][1]) = {id(mat[0][1])}')
print(f'addr(mat[1][0]) = {id(mat[1][0])}, addr(mat[1][1]) = {id(mat[1][1])}')
print(f'addr(mat[2][0]) = {id(mat[2][0])}, addr(mat[2][1]) = {id(mat[2][1])}')
输出
matrix with dimension 3 x 2 is [[0, 0], [0, 0], [0, 0]]
modified matrix is [[5, 6], [5, 6], [5, 6]]
addr(mat[0][0]) = 11094432, addr(mat[0][1]) = 11094464
addr(mat[1][0]) = 11094432, addr(mat[1][1]) = 11094464
addr(mat[2][0]) = 11094432, addr(mat[2][1]) = 11094464
方法2:外部1个列表理解,内部1个连接操作
Python3
rows = 3
cols = 2
mat = [[0]*cols for _ in range(rows)]
print(f'matrix with dimension {rows} x {cols} is {mat}')
# editing the individual elements
mat[0][0], mat[0][1] = 1,2
mat[1][0], mat[1][1] = 3,4
mat[2][0], mat[2][1] = 5,6
print(f'modified matrix is {mat}')
# checking the memory address of first element of a row
print(f'addr(mat[0][0]) = {id(mat[0][0])}, addr(mat[0][1]) = {id(mat[0][1])}')
print(f'addr(mat[1][0]) = {id(mat[1][0])}, addr(mat[1][1]) = {id(mat[1][1])}')
print(f'addr(mat[2][0]) = {id(mat[2][0])}, addr(mat[2][1]) = {id(mat[2][1])}')
输出
matrix with dimension 3 x 2 is [[0, 0], [0, 0], [0, 0]]
modified matrix is [[1, 2], [3, 4], [5, 6]]
addr(mat[0][0]) = 11094304, addr(mat[0][1]) = 11094336
addr(mat[1][0]) = 11094368, addr(mat[1][1]) = 11094400
addr(mat[2][0]) = 11094432, addr(mat[2][1]) = 11094464
方法3:2个串联操作
Python3
rows = 3
cols = 2
mat = [[0]*cols]*rows
print(f'matrix with dimension {rows} x {cols} is {mat}')
# editing the individual elements
mat[0][0], mat[0][1] = 1,2
mat[1][0], mat[1][1] = 3,4
mat[2][0], mat[2][1] = 5,6
print(f'modified matrix is {mat}')
# checking the memory address of first element of a row
print(f'addr(mat[0][0]) = {id(mat[0][0])}, addr(mat[0][1]) = {id(mat[0][1])}')
print(f'addr(mat[1][0]) = {id(mat[1][0])}, addr(mat[1][1]) = {id(mat[1][1])}')
print(f'addr(mat[2][0]) = {id(mat[2][0])}, addr(mat[2][1]) = {id(mat[2][1])}')
输出
matrix with dimension 3 x 2 is [[0, 0], [0, 0], [0, 0]]
modified matrix is [[5, 6], [5, 6], [5, 6]]
addr(mat[0][0]) = 11094432, addr(mat[0][1]) = 11094464
addr(mat[1][0]) = 11094432, addr(mat[1][1]) = 11094464
addr(mat[2][0]) = 11094432, addr(mat[2][1]) = 11094464
在这里我们可以看到方法 1 和方法 3 的输出是*意外的*。
我们希望 mat 中的所有行在我们分别分配 1、2、3、4、5、6 后都不同。但是在 Method1 & Method3 中它们都等于 [5,6]。这表明基本上 mat[0],mat[1] & mat[2] 都在引用相同的内存,这可以通过使用Python中的 id函数检查它们的地址来进一步看到。
因此在使用 (*)运算符时要非常小心。
为了进一步理解它,我们可以使用 3 维数组,我们将有 2^3 种可能性来安排列表理解和连接运算符。这是我留给读者执行的练习。
如果使用 numpy,那么我们可以使用 reshape 方法来完成。
Python3
import numpy as np
rows = 3
cols = 2
size = rows*cols
mat = np.array([0]*size).reshape(rows,cols)