2012-05-01 23 views
4

我不確定這是一個錯誤還是一個功能。 我有一個字典被初始化爲空列表。Python字典啓動

比方說

keys =['one','two','three'] 
sets = dict.fromkeys(keys,[]) 

我觀察到的是,如果你添加任何項目的任何所有列表被修改的列表。

sets = dict.fromkeys(['one','two','three'],[]) 
sets['one'].append(1) 

{'three': [1],'two': [1], 'one': [1]} 

但是,當我這樣做是使用循環手動,

for key in keys: 
     sets[key] = [] 
sets['one'].append(1) 

{'three': [], 'two': [], 'one': [1]} 

我想第二個問題應該是默認的。

+6

這個問題有着如此不同的形狀:

>>> keys = ['one','two','three'] >>> sets = { x: [] for x in keys } >>> sets['one'].append(1) >>> sets {'three': [], 'two': [], 'one': [1]} 

對於Python 2.6及以下,字典理解可以被替換和形式。 – jamylak

+1

請放下分號。 – delnan

+0

這很可能你最好在這裏通過'collections.defaultdict'服務。聲明如下:'sets = collections.defaultdict(list)'。 –

回答

10

這就是Python在Python中的工作原理。

當您以這種方式使用fromkeys()時,您將以三次對同一列表的引用結束。當你更改一個清單時,所有三個清單都會改變。

同樣的行爲也可以在這裏看到:

In [2]: l = [[]] * 3 

In [3]: l 
Out[3]: [[], [], []] 

In [4]: l[0].append('one') 

In [5]: l 
Out[5]: [['one'], ['one'], ['one']] 

同樣,三個列表實際上三個引用相同的列表:

In [6]: map(id, l) 
Out[6]: [18459824, 18459824, 18459824] 

(注意他們是如何有相同的ID )

+2

最簡單的解釋方法,我發現,它與'mylist = []'後跟'sets = dict.fromkeys(keys,mylist)'完全相同 - 就像在這種情況下一樣,其中'mylist'是每個鍵的值,當你傳遞一個空列表時[']'它每次都是同一個空列表。原因是在Python中,變量始終是引用。 –

+1

這就是爲什麼'defaultdict'使用[默認值的工廠](http://docs.python.org/library/collections.html#collections.defaultdict.default_factory),而不是值本身。奇怪的是'dict.fromkeys'沒有遵循相同的技術。 – ovgolovin

+0

沒有這麼奇怪,幫助狀態:'dict.fromkeys(S [,v]) - >新的字典從S鍵和值等於v.' – MikeyB

5

其他答案涵蓋了'爲什麼',所以這裏是如何。

您應該使用一個修真創建所需的字典:

>>> sets = dict(((x,[]) for x in keys)) 
+0

+1提前想一步;) – moooeeeep

+0

只能在蟒蛇3字典理解。 –

+0

......或2.7以上。 – MikeyB