2014-04-05 48 views
4

這個問題比任何事情都更好奇。爲什麼同等整數的行爲與平等列表不同?

我一直在閱讀的int對象在Python(12)的執行細節,並就我所看到的,一個Python int基本上是一個C指針的結構,對不對?

所以現在的問題是,基本上,在Python 內部所以相當於在Python 2個int s,而等於複雜的類型,如list沒有指向同一個實例發生,確實:

>>> a=5 
>>> b=a 
>>> print "id a: %s, id b: %s" % (id(a), id(b)) 
id a: 40802136, id b: 40802136 
>>> b+=1 
>>> print "a: %s, b: %s" % (a, b) 
a: 5, b: 6 
>>> print "id a: %s, id b: %s" % (id(a), id(b)) 
id a: 40802136, id b: 40802112 

>>> a=[5] 
>>> b=a 
>>> print "id a: %s, id b: %s" % (id(a), id(b)) 
id a: 45930832, id b: 45930832 
>>> b.append(1) 
>>> print "a: %s, b: %s" % (a, b) 
a: [5, 1], b: [5, 1] 
>>> print "id a: %s, id b: %s" % (id(a), id(b)) 
id a: 45930832, id b: 45930832 

我的猜測是,通過查看上述實例的id是因爲修改整數會創建一個新實例並將新內存地址重新分配給該變量。我懷疑是否正確?如果是這樣,有沒有人知道有這樣的整體行爲的「歷史」決定?是否這樣程序員不會堅果當int變量分配給其他變量? (我完全沒問題,順便說一下:-D

正如我所說的,這主要是一種好奇心。先謝謝你!

+5

調用對象的'.append()'方法與將名稱與'='運算符重新綁定完全不同。它與對象的類型完全沒有關係,除了'int'沒有方法可以改變它。 http://nedbatchelder.com/text/names.html是如何在Python中使用名稱的一個很好的解釋。 – geoffspear

+1

我會說'a + = b'就像'a = a + b',但事實並非如此。列表中的'+ ='與Python中的'extend'完全相同(這很愚蠢)。 =/ – Ryan

+0

是的,你們是對的。我的例子並不好。我應該說什麼@minithech提到 – BorrajaX

回答

4

您並未修改原始整數,您正在創建一個新整數併爲其分配變量,因此id與此不同。

a = 5 
b = a 
b += 1    # created a new int 
print id(a), id(b) # different 

相同

a = 5 
b = a 
b = b + 1   # created a new int 
print id(a), id(b) # different 

list相當於將不會使用append,而是利用+

a = [5] 
b = a 
b = b + [6]  # created a new list 
print id(a), id(b) # different 

的不等價appendint S,因爲int s不能修改,但list s可以。


唯一可能令人困惑的事情是

a = [5] 
b = a 
b += [1] 
print id(a), id(b) # same 

的原因是+=運營商(不幸的是,IMO)修改原始列表,因此b += [1]b = b + [1]是不等價的語句。 (請參閱Why does += behave unexpectedly on lists?

+0

你說不幸的是允許'+ ='修改可變對象,但這就是它的全部要點!如果'a'是一個龐大的可變對象,如果後者需要創建'a'的副本,'a + = x'可能比'a = a + x'快得多。 – Blckknght

+2

@Blckknght,這是真的,但有'延長'。讓'a + = b'與'a = a + b'不同的是有點不一致。對於'tuple's,'int's和'float',操作符是等價的,但是它們不是。 –

+0

如果你抱怨''用於連接列表以及'+ ='來擴展它們,我認爲你會有一個觀點。但對於任何支持'+'的可變類型,'+ ='應該可用於執行相同的簡化。對於像Numpy數組這樣的可變數字類型,運算符顯然是正確的,並且你不希望'+ ='做一個可能非常大的數據結構的副本。 – Blckknght

相關問題