Haftungsausschluss: Ich habe keine der oben genannten Code getestet, also entschuldige ich mich, wenn es einen Fehler gibt. Außerdem habe ich die Annahme, dass wir über Python reden 3 hier, aber ich denke, dass dieser Code noch in Python funktionieren soll 2.
Nicht ohne zusätzlichen Funktionsaufruf.
Zum Beispiel, sagen wir mal Sie eine Matrix
Klasse wie folgt:
from copy import copy
class Matrix:
def __init__(self, rows):
self._rows = rows
@property
def rows(self):
return list(map(copy, self._rows))
@rows.setter
def rows(self, rows):
self._rows = list(map(copy, rows))
def cols(self):
return list(map(list, zip(*self._rows)))
@cols.setter
def cols(self, cols):
self._rows = list(map(list, zip(cols)))
def transpose(self):
self.cols = self._rows
Die transponieren Funktion würde nicht einmal verwenden müssen Liste Auspacken. Aber das verwendet immer noch zip
, von dem du erwähnt hast, dass du darüber nachdenkst, es abzuschaffen.
Wenn Sie das Entpacken der Liste verwenden möchten, müssen Sie wissen, wie viele Werte entpackt werden. Wenn Sie also variable Dimensionen unterstützen, ist dies kein No-Go. Andernfalls müssen Sie die Änderungen fest codieren.
Aber es gibt ein anderes Problem zur Hand. Da das Transponieren die Dimensionen einer nicht-quadratischen Matrix ändern würde, können Sie nicht elementweise tauschen. Ein IndexError
würde in einer solchen Situation auftreten. Sie müssten zeilen- oder spaltenweise tauschen. Um dies zu tun, müssten Sie zu einem bestimmten Zeitpunkt eine Kopie der Spalten oder Zeilen erstellen (wie im obigen Code gezeigt - beachten Sie, dass die Getter-Kopien nicht notwendig sind).
Es gibt eine Technik, die Sie verwenden könnten. Sie können Ihre mehrdimensionale Liste als eine eindimensionale Liste speichern und einfach mithilfe von Mathematik bestimmen, wo eine Zeile (oder Spalte) beginnt.Zum Beispiel könnten Sie folgendermaßen vorgehen:
class Matrix:
def __init__(self, values, number_of_columns, number_of_rows):
self._values = values
self._number_of_columns = number_of_columns
self._number_of_rows = number_of_rows
@property
def rows(self):
return [self._values[i * self._number_of_rows:(i + 1) * self._number_of_rows] for i in range(self._number_of_rows)]
@property
def cols(self):
return [self._values[i::self._number_of_columns] for i in range(self._number_of_columns)]
def transpose(self):
for i in range(self._number_of_rows):
self._values[i * self._number_of_rows:(i + 1) * self._number_of_rows], self._values[i::self._number_of_rows] = self._values[i::self._number_of_columns], self._values[i * self._number_of_columns:(i + 1) * self._number_of_columns]
self._number_of_columns, self._number_of_rows = self._number_of_rows, number_of_columns
Obwohl die erste Iteration Swaps Werte zu ihren richtigen Plätzen, in einer nicht-quadratischen Matrix, sind einige Werte verloren. Betrachten Sie zum Beispiel eine Matrix, die wie folgt aufgebaut ist: Matrix(list(range(6)), 3, 2)
. wie folgt
Jeder Durchlauf:
self._values == [0, 3, 1, 3, 2, 5]
self._values == [0, 3, 3, 2, 2, 5]
Beachten Sie, dass sie die Werte an den richtigen Stellen auf dem ersten Durchgang bringt. Aber es überschreibt Werte, die noch verschoben werden müssen. Der einzige Weg, dies zu vermeiden, ist eine Kopie zu erstellen. So Sie könnte ändern, um die transpose
Methode funktioniert wie folgt:
def transpose(self):
new_values = []
for i in range(self._number_of_rows):
new_values.extend(self._values[i::self._number_of_columns])
self._values = new_values
self._number_of_columns, self._number_of_rows = self._number_of_rows, number_of_columns
Aber das ist extrem verworren und schwer zu debuggen. Also die Moral der Geschichte ist einfach zu verwenden self.state = list(zip(*self.state))
-Es ist ziemlich einfach zu lesen und schwer zu vermasseln-oder was Sie bereits in Ihrer transpose
Methode haben.
Auf den zweiten Blick scheint es, dass Ihre transpose
Methode eine doppelte Transposition der Fall ist. Und natürlich die Umsetzung einer Transposition einer Matrix M ist identisch mit M. Sie müssen die Decke machen die innere Schleife kleiner:
def transpose(self):
for i in range(dim):
for j in range(i):
self.state[i][j], self.state[j][i] = self.state[j][i], self.state[i][j]
return self
Hier ein Rezept: https://rosettacode.org/wiki/Matrix_transposition# Python – noumenal