Wenn Sie schreiben, erhalten [x]*3Sie im Wesentlichen die Liste [x, x, x]. Das heißt, eine Liste mit 3 Verweisen darauf x. Wenn Sie diese Single dann ändern x, ist sie über alle drei Verweise darauf sichtbar:
x = [1] * 4
l = [x] * 3
print(f"id(x): {id(x)}")
# id(x): 140560897920048
print(
f"id(l[0]): {id(l[0])}\n"
f"id(l[1]): {id(l[1])}\n"
f"id(l[2]): {id(l[2])}"
)
# id(l[0]): 140560897920048
# id(l[1]): 140560897920048
# id(l[2]): 140560897920048
x[0] = 42
print(f"x: {x}")
# x: [42, 1, 1, 1]
print(f"l: {l}")
# l: [[42, 1, 1, 1], [42, 1, 1, 1], [42, 1, 1, 1]]
Um dies zu beheben, müssen Sie sicherstellen, dass Sie an jeder Position eine neue Liste erstellen. Ein Weg, dies zu tun, ist
[[1]*4 for _ in range(3)]
Dies wird [1]*4jedes Mal neu bewertet, anstatt es einmal zu bewerten und 3 Verweise auf 1 Liste zu machen.
Sie fragen sich vielleicht, warum *unabhängige Objekte nicht so erstellt werden können wie das Listenverständnis. Dies liegt daran, dass der Multiplikationsoperator *Objekte bearbeitet, ohne Ausdrücke zu sehen. Wenn Sie mit 3 *multiplizieren [[1] * 4], wird *nur die 1-Element-Liste [[1] * 4]ausgewertet, nicht der [[1] * 4Ausdruckstext. *hat keine Ahnung, wie Kopien dieses Elements erstellt werden sollen, keine Ahnung, wie eine Neubewertung vorgenommen werden soll [[1] * 4], und keine Ahnung, dass Sie überhaupt Kopien wünschen, und im Allgemeinen gibt es möglicherweise nicht einmal eine Möglichkeit, das Element zu kopieren.
Die einzige Möglichkeit *besteht darin, neue Verweise auf die vorhandene Unterliste zu erstellen, anstatt zu versuchen, neue Unterlisten zu erstellen. Alles andere wäre inkonsistent oder würde eine umfassende Neugestaltung grundlegender Entscheidungen zum Sprachdesign erfordern.
Im Gegensatz dazu bewertet ein Listenverständnis den Elementausdruck bei jeder Iteration neu. [[1] * 4 for n in range(3)]wird [1] * 4jedes Mal aus demselben Grund [x**2 for x in range(3)]neu bewertet, x**2jedes Mal neu bewertet . Jede Auswertung von [1] * 4generiert eine neue Liste, sodass das Listenverständnis das tut, was Sie wollten.
Kopiert übrigens [1] * 4auch nicht die Elemente von [1], aber das spielt keine Rolle, da Ganzzahlen unveränderlich sind. Sie können so etwas nicht tun 1.value = 2und eine 1 in eine 2 verwandeln.
[x]*33 Referenzen speichern wie[x, x, x]ist nur dann richtig, wennxes veränderlich ist. Dies funktioniert nicht für zBa=[4]*3, wo nacha[0]=5,a=[5,4,4].