2012-07-22 56 views
4

我的代碼會更清楚,我認爲 -爲什麼更新這是附加到一個列表更改列表的字典?

someList = list() 
foo = {'a':'b'} 
someList.append(foo) 
print someList 
>>> [{'a':'b'}] 
defaultbazz = {'a':2, 'b':'t', 'c':'gg'} 

for k, v in defaultbazz.iteritems(): 
    foo[k] = v 

print someList 
>>> [{'a': 2, 'c': 'gg', 'b': 't'}] 

應該不是最後一個印刷是[{'a':'b'}]?我沒有更新someList,我想把它當作是...

這在我看來,未解釋的行爲..

但是,如果這就是如何巨蟒的作品,我怎麼能找到解決方法嗎?即使設置新字典更新原來的字典。我的意思是:

someList = list() 
foo = {'a':'b'} 
someList.append(foo) 
print someList 
>>> [{'a':'b'}] 
bar = foo 
defaultbazz = {'a':2, 'b':'t', 'c':'gg'} 

for k, v in defaultbazz.iteritems(): 
    bar[k] = v 

print someList 
>>> [{'a': 2, 'c': 'gg', 'b': 't'}] 

我應該心存感激,如果有人也許可以解釋我爲什麼它的發生..

回答

11

它看起來像你期望你的字典在你將它添加到列表或將它分配給一個新變量時被複制,但這不是Python如何操作的。如果分配的字典 - 實際上,如果分配任何對象 - 你是不是創建新的對象,而是你只是給你的對象的新名稱。 (一個對象可以有多個名稱。)

所以,當你在新的名稱來編輯你的對象,而該對象改變單一實例,而這種改變是可見的,當你通過任何名稱訪問對象。

如果你要複製你的對象,那麼你可以這樣做:

bar = dict(foo) 

bar = foo.copy() 
+0

感謝您和所有人的快速解答。 – eligro 2012-07-22 14:11:32

1

日文N3 N4 N5是可變的,這意味着它們可以換。這是因爲foosomeList內,你在for-loop改變foo。看看這個簡單的例子:

a_dict = {'a':'b'} 
a_list = [a_dict] 
print a_list # [{'a':'b'}] 

#change the dict 
a_dict['a'] = 'c' 
print a_list # [{'a':'c'}] 
+0

傳遞引用是完全不同的事情。 (不是我的downvote,但是。) – delnan 2012-07-22 14:04:22

+1

有些日子,我希望它是不可能downvote東西,而不留下評論。看起來可能是因爲提及了傳遞引用而失敗,但我想我們永遠不會知道。 – kojiro 2012-07-22 14:05:46

+0

對於它的價值,[這是Python如何傳遞東西](http://stackoverflow.com/a/986145/418413)。 – kojiro 2012-07-22 14:10:23

3

詞典是mutable對象,你的腳本,因此結果。 我猜你想要一個新的目標,即在原來的copy

import copy 

someList.append(copy.copy(foo)) 
5

爲了簡化:

a = {2: 3} 
b = [a] 

b包含一個「參考」,以a(並且是dict是可變的) - 因此,如果a被修改然後經由列表b訪問a,將顯示改性a

你必須明確地創建a副本,可在這種情況下進行的:

b = [dict(a)] 

但是你應該看看copy模塊copy.copy()copy.deepcopy()

2

變量在Python只是對象的名稱。如果您從任何「附加」名稱更改對象,您將看到來自其他名稱的更改。蟒蛇從來沒有自動爲您創建副本,特別是:

someList.append(foo) 

不創建的foo副本,並把它放在someList,它追加對象foo是指到列表中。

你可以爲這個對象

bar = foo 

創建第二個名字,但這並不可以創建一個副本。特別是

foo['x'] = 42 

bar['x'] = 42 

將然後操作上完全相同的對象。你可以通過打印對象的內存地址來驗證:

print id(foo), id(bar) 

並且看到它們是相同的。

如果您需要Python中的副本,則需要明確創建一個副本。根據你所需要的,在copy模塊 - 無論是copy.copy()copy.deepcopy() - 會做你想要什麼:

import copy 
bar = copy.copy(foo) 
print id(foo), id(bar) 

現在應該打印不同的存儲位置。

相關問題