Python中不带模块的转置矩阵?

Python中不带模块的转置矩阵?,python,Python,我正在尝试在Python3.x中转换矩阵,而不使用numpy。出于某种原因,我在分配新矩阵[col\u num][row\u num]时遇到问题。例如,如果我创建了一个新的矩阵实例,比如test=Matrix([[1,2,3],[4,5,6],[7,8,9]),当它第一次通过内部For循环时,新的矩阵变成[[1,None,None],[1,None,None],[1,None,None],而不是[[1,None,None],[None,None]。我不明白为什么会发生这种情况,为什么会给列表的所

我正在尝试在Python3.x中转换矩阵,而不使用numpy。出于某种原因,我在分配
新矩阵[col\u num][row\u num]
时遇到问题。例如,如果我创建了一个新的矩阵实例,比如test=
Matrix([[1,2,3],[4,5,6],[7,8,9])
,当它第一次通过内部For循环时,新的矩阵变成
[[1,None,None],[1,None,None],[1,None,None]
,而不是
[[1,None,None],[None,None]
。我不明白为什么会发生这种情况,为什么会给列表的所有第一个元素赋值

class Matrix:
    def __init__(self, matrix):
        self.matrix = matrix

    def transpose(self):
        new_matrix = [[None] * len(self.matrix[0])] * len(self.matrix)
        row_num = 0
        for row_num in range(len(self.matrix)):
            for col_num in range(len(self.matrix[0])):
                print(new_matrix[col_num][row_num])
                print(new_matrix)

                #assignment assigning more than one variable

                new_matrix[col_num][row_num] = self.matrix[row_num][col_num]

                print(new_matrix[col_num][row_num])
                print(new_matrix)

            col_num = 0
        return new_matrix
这里有一个提示:

In [9]: arr = [[None] * 2] * 3

In [10]: arr
Out[10]: [[None, None], [None, None], [None, None]]

In [11]: arr[1][1] = 2

In [12]: arr
Out[12]: [[None, 2], [None, 2], [None, 2]]

你看到问题了吗


列表复制(
*
运算符)在包含列表中重复相同的嵌套列表对象。相反,您应该每次都创建一个新列表。

这是因为您使用以下内容构造
新矩阵:

new_matrix = [[None] * len(self.matrix[0])] * len(self.matrix)
如果您这样做:

<array-expr> * number
因为这里实际上是为每一行构建一个新列表

因此,算法应该如下所示:

class Matrix:
    def __init__(self, matrix):
        self.matrix = matrix

    def transpose(self):
        new_matrix = [[None] * len(self.matrix[0]) for _ in range(len(self.matrix))]
        row_num = 0
        for row_num in range(len(self.matrix)):
            for col_num in range(len(self.matrix[0])):
                print(new_matrix[col_num][row_num])
                print(new_matrix)

                #assignment assigning more than one variable

                new_matrix[col_num][row_num] = self.matrix[row_num][col_num]

                print(new_matrix[col_num][row_num])
                print(new_matrix)

            col_num = 0
        return new_matrix
类矩阵:
定义初始化(自身,矩阵):
self.matrix=矩阵
def转置(自):
新的_矩阵=[[None]*len(self.matrix[0]),用于范围内的u(len(self.matrix))]
行数=0
对于范围内的行数(len(self.matrix)):
对于范围内的列数(len(self.matrix[0]):
打印(新矩阵[列数][行数])
打印(新矩阵)
#分配多个变量
新矩阵[col\u num][row\u num]=self.matrix[row\u num][col\u num]
打印(新矩阵[列数][行数])
打印(新矩阵)
col_num=0
返回新矩阵
必须由

new_matrix = [[None for  j in self.matrix[0]] for i in self.matrix] 
这样,所有的无将是“不同”

但较短的方法是使用扩展列表直接构建结果:

MT= [[M[j][i] for j in range(len(M))] for i in range(len(M[0]))]

您可以使用
zip
进行转置。请参见。带高亮显示的代码(…粗体)!我印象深刻@HiroProgator:好吧,花了一些时间才弄明白怎么做,但就像Python一样,一切都很简单。这就像导入反重力:pi会记住你的把戏;也许有用。谢谢你!关于导入反重力
:我喜欢matplotlib的
xkcd样式
来绘制手动波浪图…你不需要对内部列表这样做,因为
None
s是不可变的。刚刚意识到新的_矩阵应该是=[[None for j in self.matrix]for i in self.matrix[0]],而不是相反,因为新矩阵中的行数应为原始矩阵中的/列数。除此之外,谢谢!
new_matrix = [[None for  j in self.matrix[0]] for i in self.matrix] 
MT= [[M[j][i] for j in range(len(M))] for i in range(len(M[0]))]