问题很简单,只要意识到怎么回事就能解决。
# 目标:实现矩阵,然后尝试改变矩阵坐标为(i, j)的元素的值
# 实现:用列表作为行来模拟矩阵
def initMatrix(rank=3):
"""
假定矩阵是方阵,秩(rank)默认为3
"""
matrix = []
row = [0] * rank
for i in range(rank):
matrix.append(row)
return matrix
def update(matrix, t):
'''
假定 matrix 是一个矩阵, t 是一个 tuple , t = (i, j)
将第 i 行 第 j 列的元素值更新为1
'''
matrix[t[0] - 1][t[1] - 1] = 1
return
def printMatrix(matrix):
'''假定 matrix 为一个矩阵'''
for row in matrix:
print(row)
print()
return
def main():
matrix = initMatrix()
printMatrix(matrix)
update(matrix, (2, 2))
printMatrix(matrix)
return
main()
# 输出
[0, 0, 0]
[0, 0, 0]
[0, 0, 0]
[0, 1, 0]
[0, 1, 0]
[0, 1, 0]
本意是让 (2, 2) 位置的元素改为 1,但结果是每一行的第 2 个元素都变成了 1 。
原因在于创建矩阵时:
for i in range(rank):
matrix.append(row)
这样一来,矩阵的每一行都是指向同一个列表的指针。
可用如下方法测试:
def printMatrix(matrix):
for row in matrix:
print(id(e))
return
你会发现,每一行的id
都是一样的。也就是说,它们是同一个东西。
只要对任一行的元素作操作,就相当于对每一行都进行了操作。所以这种直接 matrix.append(row)
是行不通的。
def initMatrix(rank=3):
"""
假定矩阵是方阵,秩(rank)默认为3
"""
matrix = []
row = [0] * rank
for i in range(rank):
matrix.append(row.copy()) # 用浅拷贝替代
return matrix
使用列表的乘法同样有上述问题
def initMatrix(r, c):
"""
:param r:row of matrix wanted
:param c:column of matrix wanted
:return: a 2-d array, regarded as a matrix
"""
matrix = [[0] * c] * r
return matrix
def updateMatrix(matrix, i, j, new_value):
"""
:param matrix: a 2-d list regarded as matrix to be updated
:param i: row of position to update
:param j: column of position to update
:param new_value to replace old value
:return: updated matrix
"""
matrix[i-1][j-1] = new_value
return matrix
matrix = initMatrix(3, 5)
print(matrix)
print(type(matrix))
matrix = updateMatrix(matrix, 3,5,100)
print(matrix)
for e in matrix:
print(id(e))
#输出如下:
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
<class 'list'>
[[0, 0, 0, 0, 100], [0, 0, 0, 0, 100], [0, 0, 0, 0, 100]]
2302841322304
2302841322304
2302841322304