Dies ist ein etwas unintuitives Verhalten von Variablen. Dies geschieht, weil Variablen in Python immer Verweise auf Werte sind.
Boxen und Tags
In einigen Sprachen, neigen wir dazu, über Variablen als „Box“ zu denken, wo wir Werte setzen; In Python sind sie jedoch Verweise und verhalten sich eher wie Tags oder "Spitznamen" zu Werten. Wenn Sie also 1 bis item
zuweisen, ändern Sie nur die Variablenreferenz und nicht die Liste, auf die sie verweist.
Eine grafische Darstellung kann helfen. Das Bild stellt unter die Liste von alist = [[1,2], [3,4], [5,6]]
erstellt
Da wollen wir sehen, was passiert, wenn wir Ihre erste Schleife auszuführen.
Die erste Schleife
Wenn Sie for item in alist
ausführen, fragen Sie die Interpreter jeden Wert aus der Liste zu nehmen, eine pro Zeit, legt es auf der Variable item
und in ihm eine Operation zu tun. Bei der ersten Operation, zum Beispiel, haben wir dieses neue Schema:
Beachten Sie, dass wir die Teilliste item
nicht kopieren; stattdessen wir Punkt zu ihm durch item
. Dann führen wir item = 1
aus - aber was bedeutet das?Es bedeutet, dass wir 1
, statt zeigte auf den sublist item
Punkt auf den Wert machen:
Beachten Sie, dass die alte Referenz verloren geht (es ist der rote Pfeil) und jetzt haben wir eine neue. Aber wir haben gerade eine Variable geändert, die auf eine Liste zeigt - wir haben die Liste selbst nicht verändert.
Dann treten wir in die zweite Iteration der Schleife, und jetzt item
Punkte auf dem zweiten Teilliste:
Wenn wir item = 1
ausführen, wieder, wir haben nur den variablen Punkt aonther Wert machen , ohne die Liste zu ändern:
Nun, was passiert, wenn wir die zweite Schleife ausführen?
Die zweite Schleife
Die zweite Schleife beginnt wie die erste stellen wir nach item
zur ersten Subliste beziehen:
Der erste Unterschied ist jedoch, dass wir item.append()
nennen. append()
ist eine Methode, so dass es den Wert des Objekts ändern kann, das es aufruft. Wie wir verwenden, senden wir eine Nachricht an das Objekt von item
, um den Wert 10 anzuhängen. In diesem Fall ist die Operation nicht in der Variablen gemacht, aber direkt in dem Objekt es bezieht sich! So, hier ist das Ergebnis des Aufrufs item.append()
:
Allerdings haben wir nicht nur Wert auf die Liste anhängen! Wir weisen auch den von item.append()
zurückgegebenen Wert zu. Dies wird den item
Verweis auf die Unterliste trennen, aber hier ist ein Haken: append()
gibt None
zurück.
Der None
Wert
None
ist ein Wert, der im Grunde genommen die Nichtverfügbarkeit eines entsprechenden Wert darstellt. Wenn eine Funktion None
zurückgibt, heißt es meistens: "Ich habe nichts Relevantes, um Sie zurückzugeben." append()
ändert seine Liste direkt, so dass es nichts gibt, das zurückgegeben werden muss.
Es ist wichtig, weil Sie wahrscheinlich geglaubt haben item
würde auf die angefügte Liste [1, 2, 10]
, Recht verweisen? Nein, jetzt zeigt es auf None
. Also, Sie würden den Code unten erwarten ...
alist = [[1,2], [3,4], [5,6]]
for item in alist:
item = item.append(10)
print(item)
Um so etwas wie dieses Motiv:
[1, 2, 10]
[3, 4, 10]
[5, 6, 10]
Aber diese ist nicht passieren. Diese ist, was passiert:
>>> alist = [[1,2], [3,4], [5,6]]
>>> for item in alist:
... item = item.append(10)
... print(item)
...
None
None
None
Doch wie wir kommentierte die append()
Methode die Listen selbst verändert. Also, während die Variable nach der Zuweisung nutzlos war, wird die endgültige Liste geändert!
>>> print alist
[[1, 2, 10], [3, 4, 10], [5, 6, 10]]
Wenn Sie die beigefügten Liste innerhalb der Schleife verwenden möchten, ordne einfach nicht die Methode zurückgegebenen Wert zu item
. Tun Sie dies:
>>> alist = [[1,2], [3,4], [5,6]]
>>> for item in alist:
... item.append(10)
... print item
...
[1, 2, 10]
[3, 4, 10]
[5, 6, 10]
Dies funktioniert, weil item
noch auf der Liste verweisen.
Fazit
Referenzen sind etwas komplex zunächst, geschweige denn Meister zu verstehen. Sie sind jedoch sehr mächtig und können gelernt werden, wenn Sie Beispielen folgen. Ihr Beispiel ist ein bisschen kompliziert, weil hier mehr passiert.
Die Python Tutor kann Ihnen helfen zu verstehen, was vor sich geht, weil es jeden Schritt grafisch ausführt. Check your own code running there!
Zuerst ändern, wenn es wie folgt verwendet wird: 'für Element in Alist: Alist [Alist.Index (Element)] = 1' So' Element' ist lokale Variable in einer Schleife, nichts außerhalb tun. – dsgdfg