2016-03-30 15 views
2

Ich habe gerade festgestellt, dass der Pythonic Swap nicht immer funktioniert.Pythonic tauschen x, y = y, x funktioniert nicht?

def swap(x,y): 
    x,y = y,x 

a = 1 
b = 2 
swap(a,b) 

print b 

Ergebnis: 2

Warum der pythonic Weg Variablen tauschen in diesem Fall nicht funktionieren? Brauche ich vorübergehend eine Variable?

+1

was genau erwarten Sie? 'print b' wird tatsächlich' 2' becuase 'b = 2' ausgeben – Deusdeorum

+2

die meisten Python-Objekte sind nicht veränderbar ... ergo tauschst du eigentlich nicht ... du erschaffst gerade eine lokale x, y-Variable innerhalb der Funktion, so dass 'x = y, y = x ', aber es gilt nur, solange Sie sich im Methodenbereich befinden –

+1

@JoranBeasley das hat nichts mit Veränderlichkeit zu tun. Das Verhalten wäre dasselbe, wenn Sie Listen für diese Funktion übergeben hätten. – timgeb

Antwort

1

Sie sind nie zurückgekehrt und haben die Ergebnisse zugewiesen. Ansonsten, wie Joran sagte, erstellen Sie nur lokale Variablen in der Funktion. Zum Beispiel:

def swap(a, b): 
    print "swap called" 
    return (b,a) 

a = 1 
b = 2 

print a,b 
a,b = swap(a,b) 
print a,b 

Ergebnisse in den folgenden angezeigt werden:

 
1 2 
swap called 
2 1 
+1

Mit anderen Worten, Python ist pass-by-value. –

+0

@JamesBuck nein, Python ist Pass-by-Assignment. – timgeb

+0

@timgeb ist es Pass-by-Wert in der gleichen Weise wie C und Java sind. Genauer gesagt als Pass-by-Reference-Wert. –

3

In der ersten Zeile der Funktionsdefinition

def swap(x,y): 

x und y sind aufgerufen, so formale Parameter. Wenn Sie anrufen

swap(a, b) 

Sie vorbei in a und b als tatsächlichen Argumente.

Was jetzt passiert, ist, dass Python neue Namen für die eigentlichen Argumente schafft man in vergangen.

im Funktionskörper x ist nun ein neuer Name für das Integer-Objekt im Speicher, die auch den Namen a hat. y ist jetzt ein neuer Name für das Integer-Objekt im Speicher, das auch den Namen b trägt. Aus diesem Grund ist Python weder Call-by-Value noch Call-by-Reference, sondern wird am besten als call-by-assignment beschrieben.

Entgegen der weit verbreiteten Meinung funktioniert das Aufrufen von Funktionen und Zuweisungen für veränderbare und unveränderbare Parameter genau gleich. Sie werden das gleiche Verhalten sehen Sie für veränderbare Werte beobachten:

>>> def swap(x,y): 
...  x,y = y,x 
... 
>>> a = [1] 
>>> b = [2] 
>>> swap(a,b) 
>>> a 
[1] 
>>> b 
[2] 

Also, wenn Sie verstehen, wie Aufgaben in Python arbeiten, werden Sie haben auch verstanden, wie Funktion Arbeit nennt.

Um ein Beispiel zu machen: Wenn Sie nicht gleichwertig gewesen wäre, den Code schreiben hat eine Funktion, zu:

a = 1 
b = 2 
x = a 
y = b 
x,y = y,x 
del x 
del y 

In Zeile 3, erstellen Sie einen neuen Namen x für die Integer-Objekt, das geht auch unter dem Namen a. Zeile 4 folgt derselben Logik. In Zeile 5 erstellen Sie das Tupel (y, x) mit dem Wert (2, 1) auf der rechten Seite, der dann ausgepackt wird, d.der Name x ist den Wert zugewiesen 2 und der Name y auf den Wert zugewiesen 1:

>>> a = 1 
>>> b = 2 
>>> x = a 
>>> y = b 
>>> x,y = y,x 
>>> x 
2 
>>> y 
1 

Wichtig ist hier zu beachten ist, dass a und b nie für die Wertnamen werden gestoppt 1 und 2 jeweils:

>>> a 
1 
>>> b 
2 

die letzten beiden Zeilen lösen nur die Namen x und y was in etwa gleichwertig ist, was in Ihrer Funktion geschieht, wenn Sie ihren Umfang verlassen. Beachten Sie, dass die Namen a und b immer noch gebunden sind, nachdem x und y gelöst wurden.

>>> a 
1 
>>> b 
2