Python Variablen Zuweisung in eine for-Schleife
Verstehe ich, dass in Python reguläre c++ - Stil-variable Zuordnung wird ersetzt durch Verweise auf Sachen ie
a=[1,2,3]
b=a
a.append(4)
print(b) #gives [1,2,3,4]
print(a) #gives [1,2,3,4]
aber ich bin immer noch verwirrt, warum eine analoge situation mit den grundlegenden Arten zB. Ganzzahlen funktioniert das anders?
a=1
b=a
a+=1
print(b) # gives 1
print(a) # gives 2
Aber warte, es wird noch verwirrender, wenn man bedenkt, Schleifen!
li=[1,2,3]
for x in li:
x+=1
print(li) #gives [1,2,3]
Das ist, was ich erwartet habe, aber was passiert, wenn wir tun:
a,b,c=1,2,3
li=[a,b,c]
for x in li:
x+=1
print(li) #gives [1,2,3]
Vielleicht ist meine Frage sollte sein, wie eine Schleife über eine Liste von Ganzzahlen und wechseln Sie Sie ohne Karte (), wie muss ich eine if-Anweisung drin. Das einzige, was ich kann kommen, kurz mit
for x in range(len(li)):
Do stuff to li[x]
ist die Verpackung von den ganzen zahlen in einer Liste der Elemente. Aber es muss einen besseren Weg geben.
b=a
ist eine Ressource-Referenz. Also es wird sich auf den gleichen Speicher, so bleibt es verbunden. Diefor
Schleife, die Sie tun, wird eine neue Instanz (x
) und wird somit nicht auf dieli
es sei denn, Sie schreiben, die änderung zurück zu der Liste.- Vielleicht dieser link: stackoverflow.com/questions/4081217/... klären Sie aoome Dinge zu diesem Thema.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sind Sie hier ändern der Liste. Inhalt der Liste ändert, aber die Liste Identität bleibt.
Dies ist jedoch eine Umwidmung. Weisen Sie ein anderes Objekt zu
a
.Beachten Sie, dass, wenn Sie Tat
a += [4]
im 1. Beispiel, hättest du gesehen das gleiche Ergebnis. Dies kommt von der Tatsache, dassa += something
ist das gleiche wiea = a.__iadd__(something)
, mit einem fallback aufa = a.__add__(something)
wenn__iadd__()
existiert nicht.Der Unterschied ist, dass
__iadd__()
versucht, seine Arbeit zu tun, "inplace", durch das verändern des Objekts, es funktioniert auf und es wieder. Soa
bezieht sich auf die gleiche wie vorher. Dies funktioniert nur mit veränderliche Objekte wie Listen.Auf unveränderliche Objekte wie Ganzzahlen
__add__()
genannt wird. Es gibt ein anderes Objekt, das führt zua
zeigt auf ein anderes Objekt als zuvor. Es gibt keine andere Wahl, als int-Werte sind unveränderlich.Hier
x += 1
bedeutet das gleiche wiex = x + 1
. Es ändert wox
bezieht, aber nicht die Inhalte der Liste.tritt jede Liste position den alten Wert + 1.
Gut, Sie müssen denken veränderlich und unveränderlich geben.
Für eine Liste, es ist veränderlich.
Für eine ganze Zahl, es ist unveränderlich, das heißt, Sie beziehen sich auf ein neues Objekt, wenn Sie es verändern. Wenn eine+=1 ausgeführt wird, wird eine zugewiesen werden, ein neues Objekt, aber b ist immer noch auf die gleiche.
Das wichtigste hier sind die Variablen Namen. Sie sind wirklich nur Schlüssel zu einem Wörterbuch. Sie sind entschlossen, zur Laufzeit, abhängig vom aktuellen Bereich.
Lassen Sie uns einen Blick, welche Namen Sie den Zugang in Ihrem code. Die die einheimischen - Funktion hilft uns dabei: Er zeigt die Namen im lokalen Bereich (und Ihren Wert). Hier ist Ihr code, mit einigen debugging-Ausgabe:
(Hinweis: ich ausgebaut
x += 3
zux = x + 3
um die Sichtbarkeit zu erhöhen für den Namen zugreift, Lesen und schreiben.)Zunächst binden Sie die Liste
[1, 2, 3]
auf den Namena
. Dann, Sie die Liste Durchlaufen. Während jeder iteration den Wert gebunden ist, den Namenx
im aktuellen Bereich. Ihre Aufgabe weist dann einen anderen Wert, umx
.Hier ist die Ausgabe
Ohne Punkt sind Sie den Zugriff auf
a
die Liste, und damit wird sich nie ändern.Um Ihr problem zu beheben, würde ich verwenden Sie die enumerate-Funktion, um den index zusammen mit dem Wert und klicken Sie dann auf die Liste mit den Namen
a
zu ändern.Ausgabe:
Hinweis: möchten Sie möglicherweise wickeln Sie diese Beispiele in eine Funktion, um zu vermeiden das überladen globalen namespace.
Mehr über Bereiche, Lesen Sie die Kapitel in der Python-tutorial. Um weiter zu untersuchen, verwenden Sie den globals Funktion zu sehen, die Namen der globalen namespace. (Nicht zu verwechseln mit der
global
Schlüsselwort, beachten Sie den fehlenden 's'.)Spaß haben!
Für ein C++-Kopf ist es am einfachsten, tho denke, dass jedes Python-Objekt ist ein Zeiger. Wenn Sie schreiben
a = [1, 2, 3]
Sie im wesentlichen schreibenList * a = new List(1, 2, 3)
. Wenn Sie schreibena = b
Sie im Grunde schreibenList * b = a
.Aber, wenn Sie aus tatsächlichen Elemente aus den Listen, die diese Elemente zufällig zahlen. Die zahlen sind unveränderlich; hält einen Zeiger auf ein immutable object ist ungefähr so gut wie die Abhaltung dieses Objekt von Wert.
Damit Ihre
for x in a: x += 1
im wesentlichenwas natürlich keine Wirkung hat.
Wenn die Liste Elemente von veränderlichen Objekten, die Sie könnte mutieren Sie genau so, wie Sie schrieb. Siehe:
Aber es sei denn, Sie haben einen zwingenden Grund (z.B. eine Liste von Millionen von Objekten unter starker Auslastung) Sie sind besser dran, eine Kopie der Liste, Anwendung einer transformation und Optional einen filter. Dies ist leicht getan mit einer Liste Verständnis:
Entweder das, oder Sie schreiben eine explizite Schleife, wird eine weitere Liste:
1+2
sucht dienp_add
- Ablagefach auf den erstenPyLongObject *
und ruft es mit den anderenPyLongObject *
als argument. (Es ist sogar noch komplizierter als das, aber das ist genug, um Ihnen die Idee. Es ist kein unboxing.)Ihre Frage hat mehrere Teile, es wird also schwer sein für eine Antwort auf alle von Ihnen. glglgl hat einen großartigen job gemacht, auf den meisten davon, aber deine Letzte Frage ist noch unerklärt:
"Ich brauche eine if-Anweisung drin" bedeutet nicht, dass Sie nicht verwenden können
map
.Zuerst, wenn Sie möchten, dass die
if
wählen Sie die Werte, die Sie behalten möchten,map
hat einen guten Freund namens- filter
, was genau das macht. Zum Beispiel, um nur die ungeraden zahlen, aber hinzufügen, um jeden von Ihnen, Sie könnten dies tun:Oder nur dieses:
Wenn auf der anderen Seite wollen Sie die
if
zur Steuerung der Ausdruck selbst—z.B., zu ergänzen, 1 die ungeraden zahlen aber lassen Sie auch diejenigen, die allein, Sie können einif
Ausdruck der gleichen Weise, die Sie möchten, verwenden Sie eine if-Anweisung:Zweite, Verstehens sind im Grunde gleichwertig zum
map
undfilter
, aber mit Ausdrücke statt Funktionen. Wenn Ihr Ausdruck nur "diese Funktion aufrufen", dann verwenden Siemap
oderfilter
. Wenn die Funktion wäre einfach ein lambda-Ausdruck auswerten dieses Ausdrucks", dann verwenden Sie ein Verständnis. Die beiden oben genannten Beispiele bekommen mehr lesbar, so:Können Sie etwas wie das hier tun:
li = [x+1 for x in li]