2016-08-26 42 views
6

下面是一個例子:Python:什麼時候兩個變量指向內存中的同一個對象?

l = [1, 5, 9, 3] 
h = l 

h[0], h[2] = h[2], h[0] 

print(h) # [9, 5, 1, 3] 
print(l) # [9, 5, 1, 3] 

h = h*2 
print(h) # [9, 5, 1, 3, 9, 5, 1, 3] 
print(l) # [9, 5, 1, 3] 

我的理解是,在調用設置h = l只會在同一個項目點h內存中l在指指點點。那麼爲什麼在最後3行中,hl不能給出相同的結果呢?

+1

你改變'h'指向什麼時候再次分配給'h'。 – user2357112

+0

這取決於變量的值是否可變。列表是可變的,整數不是。 –

+0

設置'h = l'確實將'h'指向'l'。但是,然後設置'h = h * 2'將'h'指向別的東西。 – BrenBarn

回答

2

作業確實使h指向與l相同的項目。但是,它不會永久焊接兩者。當您更改hh = h * 2時,您告訴Python在內存中的其他地方構建雙倍版本,然後使h指向加倍版本。您沒有給出任何指示來更改l;仍然指向原來的項目。

7

這是相當簡單的檢查,運行這個簡單的測試:

l = [1, 5, 9, 3] 
h = l 

h[0], h[2] = h[2], h[0] 

print(h) # [9, 5, 1, 3] 
print(l) # [9, 5, 1, 3] 

print id(h), id(l) 
h = h * 2 
print id(h), id(l) 

print(h) # [9, 5, 1, 3, 9, 5, 1, 3] 
print(l) # [9, 5, 1, 3] 

正如你所看到的,因爲行h = h * 2中,H公司的ID已被更改

這是爲什麼?當您使用*運算符時,它將創建一個新列表(新的內存空間)。在你的情況下,這個新的列表被分配到舊的H參考,這就是爲什麼你可以看到ID是不同的後h = h * 2

如果你想知道更多關於這個問題,請確保你看看Data Model鏈接。

+0

是的,但這並不告訴我*爲什麼* – AlanH

+0

@AlanH好吧,我已經編輯了我的答案 – BPL

1

任何時候當你分配給一個變量時,它的標識(內存地址)通常會發生變化 - 它不會改變的唯一原因是你碰巧給它分配了它已經保存的值。所以,你的陳述h = h * 2導致h成爲一個全新的對象 - 其價值恰巧基於h的先前值,但與其身份無關。

4

h = h * 2h分配給新的列表對象。

你可能要修改就地h

h *= 2 
print(h) # [9, 5, 1, 3, 9, 5, 1, 3] 
print(l) # [9, 5, 1, 3, 9, 5, 1, 3] 
+0

簡短而親切...... +1'h + = h * 2'也可以。 :) –

+0

@ l'l l這是行得通的,但不是它的三倍而不是兩倍?你的意思是'h + = h'? –

+1

是的,謝謝你的糾正,這就是我的意思,我的手機不知何故離開了* 2 ...在那裏。 –

1

這是棘手,但是當你乘的列表,你正在創建一個新的列表。

l = [1, 5, 9, 3] 
h = l 

'l'和'h'現在指的是內存中的相同列表。

h[0], h[2] = h[2], h[0] 

print(h) # [9, 5, 1, 3] 
print(l) # [9, 5, 1, 3] 

您在h交換的值,因此其值在l改變。這是有道理的,當你想想他們爲不同的名稱同一對象

h = h * 2 

print(h) # [9, 5, 1, 3, 9, 5, 1, 3] 
print(l) # [9, 5, 1, 3] 

當乘以h * 2,要創建一個新名單,所以現在只能l將原有列表對象。

>>> l = [1, 5, 9, 3] 
>>> h = l 
>>> id(h) == id(l) 
True 
>>> id(h) 
139753623282464 
>>> h = h * 2 
>>> id(h) == id(l) 
False 
>>> id(h) 
139753624022264 

如何看相乘後的hid變化?與其他列表操作不同,*運算符創建了一個新列表,如append()這些列表會更改當前列表。

>>> h.append(1000) 
>>> id(h) 
139753623282464 # same as above! 

希望這有助於!

相關問題