在for-loop中,当我使用'追加'要向列表中添加新元素,之前添加的元素也会更改

时间:2017-12-06 14:37:18

标签: python

我想在不使用Numpy的情况下获得矩阵B的转置。当我使用'追加'要向列表中添加新元素,之前添加的元素也会更改。我该如何解决?

from decimal import *

B = [[1,2,3,5], 
     [2,3,3,5], 
     [1,2,5,1]]

def shape(M):
    r = len(M)
    c = len(M[0])
    return r,c

def matxRound(M, decPts=4):
    for p in M:
        for index in range(len(M[0])):
            p[index] = round(p[index], decPts)

def transpose(M):
    c_trans, r_trans = shape(M)
    new_row = [0]*c_trans
    trans_M = []
    for i in range(r_trans):
        for j in range(c_trans):
            new_row[j] = M[j][i]
        print 'new_row',new_row
        print 'trans_M before append',trans_M
        trans_M.append(new_row)
        print 'trans_M after append',trans_M
    return trans_M

print transpose(B)

输出在这里:

new_row [1, 2, 1]
trans_M before append []
trans_M after append [[1, 2, 1]]
new_row [2, 3, 2]
trans_M before append [[2, 3, 2]]
trans_M after append [[2, 3, 2], [2, 3, 2]]
new_row [3, 3, 5]
trans_M before append [[3, 3, 5], [3, 3, 5]]
trans_M after append [[3, 3, 5], [3, 3, 5], [3, 3, 5]]
new_row [5, 5, 1]
trans_M before append [[5, 5, 1], [5, 5, 1], [5, 5, 1]]
trans_M after append [[5, 5, 1], [5, 5, 1], [5, 5, 1], [5, 5, 1]]
[[5, 5, 1], [5, 5, 1], [5, 5, 1], [5, 5, 1]]

2 个答案:

答案 0 :(得分:0)

我将完成@glibdud评论的答案:

您现在正在做的是创建一个符合Transpose需求的列表。 您正在创建新矩阵。

然后,您将转置后的值附加到新矩阵中......而不创建新的转置列表。 然后会发生的是你修改刚刚追加的最后一个列表,并尝试再次附加它。

所以最后,你将4个相同的列表添加到新矩阵中。由于4个列表指向内存中的相同地址,因为它们是同一个对象,因此新矩阵有4个相同的行。

答案 1 :(得分:0)

我知道在不使用Numpy(应该是首选方式)的情况下执行矩阵转置的最pythonic方式是使用list unpacking(列表扩展)和内置zip函数shiny.reactlog

但是,transposed = list(zip(*B))返回元组,而原始矩阵是列表列表。因此,如果您想保留结构,可以使用zip()