2010-05-09 11 views
15

Kann jemand erklären, warum das Beispiel mit Ganzzahlen unterschiedliche Werte für x und y ergibt und das Beispiel mit der Liste ergibt, dass x und y das gleiche Objekt sind?Python-Referenzen

x = 42 
y = x 
x = x + 1 
print x # 43 
print y # 42 

x = [ 1, 2, 3 ] 
y = x 
x[0] = 4 
print x # [4, 2, 3] 
print y # [4, 2, 3] 
x is y # True 
+1

'y = Liste (x)' * * –

+0

Betrogene oft über – SilentGhost

+0

wow.! Das sieht genau so aus, wie ich im letzten Monat gefragt habe in http://stackoverflow.com/questions/2573135/2573965#2573965 – wescpy

Antwort

8

Da ganze Zahlen unveränderlich sind, während Liste veränderbar sind. Sie können aus der Syntax sehen. In x = x + 1 vergeben Sie tatsächlich x einen neuen Wert (es ist allein auf der LHS). In x[0] = 4 rufen Sie den Indexoperator in der Liste auf und geben ihm einen Parameter - er entspricht tatsächlich x.__setitem__(0, 4), wodurch offensichtlich das ursprüngliche Objekt geändert wird und kein neues Objekt erstellt wird.

+0

Ist es nicht möglich, Verweise auf unveränderbare Objekte zu erhalten? – hekevintran

+3

Alle "Variablen" sind Referenzen. Der Unterschied besteht darin, dass Sie unveränderliche Objekte nicht ändern können. Sobald sie erstellt werden, ändern sie sich nie - jede versuchte Änderung wird ein neues Objekt erstellen. –

+2

Die Angabe "einen neuen Wert zu x zuweisen" ist unaufrichtig und möglicherweise verwirrend. Was passiert, ist, dass eine Referenz auf ein neues Objekt (Ergebnis von x + 1) an den Namen x gebunden ist. Python hat nicht das Konzept von Lvalue/rvalue, da auf alles verwiesen wird - daher ist die Unterscheidung wichtig. –

0

Das liegt daran, wenn Sie eine Liste oder ein Tupel in Python haben, erstellen Sie einen Verweis auf ein Objekt. Wenn Sie sagen, y = x verweisen Sie auf das gleiche Objekt mit y wie x tut. Also, wenn Sie das Objekt von x y bearbeiten ändert sich damit.

+0

Weniger verwirrend als akzeptierte Antwort. –

+2

"Wenn Sie eine Liste oder ein Tupel haben" ist ziemlich irreführend. – Ryan

+0

Ja, tut mir leid. Was ich sagen wollte war, dass es egal ist, welche der beiden, da sie beide unveränderlich sind. – Bloeper

4

Wenn Sie das tun y = x, y und x sind die Referenz auf das gleiche Objekt. Aber Zahlen sind unveränderlich, und wenn Sie x + 1 tun, wird die neue Ganzzahl erstellt:

>>> x = 1 
>>> id(x) 
135720760 
>>> x += 1 
>>> id(x) 
135720748 
>>> x -= 1 
>>> id(x) 
135720760 

Wenn Sie ein veränderbares Objekt (zB Liste, Klassen selbst definiert) haben, x geändert wird, wenn y geändert wird, weil sie zeigen zu einem einzelnen Objekt.

0

Wie die vorherigen Antworten sagten, weist der von Ihnen geschriebene Code verschiedenen Namen wie Aliasen das gleiche Objekt zu. Wenn Sie eine Kopie der ursprünglichen Liste der neuen Variablen (Objekt tatsächlich) Verwendung dieser Lösung zuweisen möchten:

>>> x=[1,2,3] 
>>> y=x[:] #this makes a new list 
>>> x 
[1, 2, 3] 
>>> y 
[1, 2, 3] 
>>> x[0]=4 
>>> x 
[4, 2, 3] 
>>> y 
[1, 2, 3]