2010-05-09 101 views
15

有人可以解釋爲什麼整數的例子爲x和y產生不同的值,而列表的例子中x和y是相同的對象?Python的參考

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 =列表(x)'* – 2010-05-09 09:07:58

+0

欺騙了許多倍 – SilentGhost 2010-05-09 09:08:25

+0

哇!這看起來就像我上個月在問起http://stackoverflow.com/questions/2573135/2573965#2573965 – wescpy 2010-05-10 04:30:36

回答

8

因爲整數是不可變的,而列表是可變的。你可以從語法中看到。在x = x + 1中,您實際上正在爲x分配一個新值(它僅在LHS中)。在x[0] = 4中,您正在調用列表中的索引運算符並給它一個參數 - 它實際上相當於x.__setitem__(0, 4),這顯然會更改原始對象,而不是創建新對象。

+0

不可能獲得對不可變對象的引用嗎? – hekevintran 2010-05-09 10:06:56

+3

所有「變量」都是引用。差別在於你不能改變不可變的對象。一旦它們被創建,它們就不會改變 - 任何嘗試的改變都會創建一個新的對象。 – 2010-05-09 10:11:09

+2

陳述「給x分配一個新值」是不真誠的,可能會令人困惑。發生的事情是對新對象的引用(x + 1的結果)綁定到名稱x。 Python並沒有左值/右值的概念,因爲一切都被引用 - 所以區別很重要。 – 2010-05-09 13:02:52

0

這是因爲當你在Python中有一個列表或元組時,你可以創建一個對象的引用。 當你說y = x時,你引用與y相同的對象。 所以,當你編輯x的對象隨着它而改變。

+0

比接受的答案更容易混淆。 – 2013-03-12 21:41:37

+2

「當你有一個列表或一個元組」是相當具有誤導性的。 – Ryan 2013-06-20 14:01:44

+0

對,我很抱歉。 我的意思是說,兩者中的哪一個並不重要,因爲它們都是不可變的。 – Bloeper 2013-07-19 08:29:15

4

如果你這樣做y = x,Y和X是參照同一個對象。但整數是不變的,當你做x + 1,創建新的整數:

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

當你有一個可變對象(如列表,自己定義的類),每當y發生了改變x被改變,因爲它們指向到一個單一的對象。

0

正如之前的答案所說,您寫的代碼將不同的名稱(如別名)分配給同一個對象。 如果你想原始列表的副本分配給新的變量(對象實際上) 使用此解決方案:

>>> 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]