2017-01-27 3 views
2

Ich versuche, eine Matrix in Python 3.x zu transponieren, ohne numpy zu verwenden. Aus irgendeinem Grund habe ich Probleme mit der Zuweisung von new_matrix[col_num][row_num]. Wenn ich zum Beispiel eine neue Instanz von Matrix wie test = Matrix([[1,2,3,],[4,5,6],[7,8,9]]) erstelle, wird new_matrix beim ersten Durchlauf durch die innere for-Schleife [[1,None,None],[1,None,None],[1,None,None]] anstelle von [[1,None,None],[None,None,None],[None,None,None]]. Ich kann nicht herausfinden, warum das passiert und warum es ALLEN ersten Elementen von Listen einen Wert zuweist.Matrix in Python ohne Module transponieren?

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 
+0

Sie 'zip' verwenden könnten umzusetzen. Siehe http://stackoverflow.com/questions/10169919/python-matrix-transpose-and-zip. – kennytm

Antwort

2
new_matrix = [[None] * len(self.matrix[0])] * len(self.matrix) 

müssen diese Weise durch

new_matrix = [[None for j in self.matrix[0]] for i in self.matrix] 

ersetzt werden, die alle die None wird "differents" sein.

aber der kürzere Weg ist, um das Ergebnis direkt mit der Erweiterung Listen zu erstellen:

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

Sie müssen dies nicht für die innere Liste tun, da 'None's unveränderlich sind. –

+0

@WVO: Sie haben Recht. –

+0

Habe gerade erkannt, dass new_matrix = [[None für j in self.matrix] für i in self sein sollte.Matrix [0]], nicht umgekehrt, weil die Anzahl der Zeilen in der neuen Matrix die Anzahl von/columns/in der ursprünglichen Matrix sein sollte. Ansonsten, danke! – gridproquo

1

Hier ist ein Tipp:

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]] 

Sehen Sie das Problem?

Die Listenreplikation (*-Operator) wiederholt das gleiche verschachtelte Listenobjekt innerhalb der enthaltenen Liste. Stattdessen sollten Sie jedes Mal eine neue Liste erstellen.

2

Das ist, weil Sie die newmatrix mit Konstrukt:

new_matrix = [[None] * len(self.matrix[0])] * len(self.matrix) 

Wenn Sie das tun:

<array-expr> * number 

Sie kopieren nicht diese Liste, Sie kopieren Sie die Referenz. Das bedeutet, dass, wenn Sie newmatrix[0] manipulieren Sie auch newmatrix[1] manipulieren usw.

Sie es mit der Liste Verständnis lösen sollte:

new_matrix = [[None] * len(self.matrix[0]) for _ in range(len(self.matrix))] 

Da hier Sie tatsächlich eine neue Liste für jede Zeile konstruieren.

So sollte der Algorithmus aussehen:

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
+0

Code mit Hervorhebung (... gut fett)! Ich bin beeindruckt! –

+0

@hiroprotagonist: Nun, es dauerte einige Zeit, um herauszufinden, wie es geht, aber wie Python ist alles so einfach auf SO. Es ist wie 'import antigravity': p –

+2

Ich werde diesen Trick von euch behalten; kann nützlich sein. Dank dafür! apropos 'import antigravity': ich liebe' xkcd-style' für matplotlib zum Zeichnen von hand-welligen Plots ... –