嵌套for循环转置矩阵

时间:2018-01-11 16:27:18

标签: python matrix nested

def transpose_matrix(matrix):
    n = len(matrix)
    vertical_to_horizontal = [[0]*n]*n
    for i in range(n):
        for j in range(n):
            vertical_to_horizontal[i][j] = matrix[j][i]
    return vertical_to_horizontal


print(transpose_matrix([[1,2],[3,4]]))

该函数应该转置n*n矩阵,但我得到[[2, 4], [2, 4]]而不是正确答案([1,3],[2,4])。

我知道还有其他方法来转置矩阵,但我的问题是理解为什么上面的代码没有给出预期的结果。

2 个答案:

答案 0 :(得分:2)

您的算法是正确的,问题在于您在开始时使用

创建空矩阵的方式
vertical_to_horizontal = [[0]*n]*n

内部[0]*n会创建一个列表[0, 0]

然后,外部*运算符创建一个列表,该列表引用此内部列表的两倍 - 同一个对象。

n = 2
v_to_h = [[0]*n] * n
print(id(v_to_h[0]), id(v_to_h[1]))
#140243497120456 140243497120456

矩阵中的两个[0,0]列表实际上是相同的对象,正如它们的相同ID所示。所以,当我们做的时候

v_to_h[0][0] = 5

我们更新v_to_h [0]的第0个元素,但是v_to_h [0]和v_to_h [1]是同一个对象,所以我们得到矩阵中相同列表的两倍:

print(v_to_h)
#[[5, 0], [5, 0]]

如果要阻止这种情况,则必须创建不同的内部列表,因此请勿使用*运算符。

您可以使用列表推导,如:

n = 2
v_to_h = [[0]*n for i in range(n)]
print(id(v_to_h[0]), id(v_to_h[1]))
#140243437130184 140243512804488

这里,我们的两个列表是不同的对象。

所以,你的代码可能是:

def transpose_matrix(matrix):
    n = len(matrix)
    vertical_to_horizontal = [[0]*n for i in range(n)]
    for i in range(n):
        for j in range(n):
            vertical_to_horizontal[i][j] = matrix[j][i]
    return vertical_to_horizontal


print(transpose_matrix([[1,2],[3,4]]))
#[[1, 3], [2, 4]]

这可以达到预期的效果 - 当然,有更短更有效的方法来转置矩阵,如评论中所示。

答案 1 :(得分:-1)

def transpose_matrix(matrix):
    n = len(matrix)
    vertical_to_horizontal = []
    for i in range(n):
        vertical_to_horizontal.append([i]*n)
        for j in range(n):
            vertical_to_horizontal[i][j] = matrix[j][i]
    return vertical_to_horizontal


print(transpose_matrix([[1,2],[3,4]]))