2011-03-12 83 views
3

我是Python新手(也是編程)。Python:如何在for循環中交替鍵來修改字典值?

我想通過交替字典的鍵來修改for循環中的字典。我寫了下面的代碼,這是unsccessful,但是:

#coding: utf-8 
dict1 = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'} 
dict2 = dict.fromkeys(dict1.values(),[]) 

for key in dict2: 
    if key == 'value1': 
     dict2[key].extend(['test1', 'test2']) 
    elif key == 'value2': 
     dict2[key].extend(['test3', 'test4']) 
    elif key == 'value3': 
     dict2[key].extend(['test5', 'test6']) 

print (dict2['value1']) 
print (dict2['value3']) 

我希望的結果是:

['test5', 'test6'] 
['test1', 'test2'] 

,但事實上,我:

['test5', 'test6', 'test3', 'test4', 'test1', 'test2'] 
['test5', 'test6', 'test3', 'test4', 'test1', 'test2'] 

我想這個問題可能來自我使用「dict.fromkeys」從另一個字典中製作字典,但我不明白爲什麼它是有問題的,即使是這種情況。

感謝您的關注。期待您的建議。

回答

6

dict2所有值實際上是相同的列表實例,因爲傳遞[]dict.fromkeys()只創建一個列表實例。嘗試

dict2 = dict((v, []) for v in dict1.values()) 
+0

我得到了我期望的結果,我明白我錯過了什麼。謝謝! – 2011-03-12 10:39:55

+0

@miyazaki_tara:如果你喜歡這個答案最好,你應該接受它。 – martineau 2011-03-12 22:13:56

0

遍歷yourdict.keys()(這將返回一個列表,這樣就不會被任何改變字典受到影響)

+0

只有字典中的值是在循環中,這是很好的內部改性。 – 2011-03-12 10:05:48

0

問題是dict.fromkeys()初始化每個項目與同一個對象

dict2 = dict((x, []) for x in dict1.values()) 
+0

謝謝!我現在明白我錯過了什麼。 – 2011-03-12 10:44:09

2

問題是你使用了一個可變對象作爲值初始值設定項。每個值都是相同的對象。

Python2> dict1 = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'} 
Python2> dict2 = dict.fromkeys(dict1.values(),[]) 
Python2> dict2 
{'value1': [], 'value2': [], 'value3': []} 
Python2> dict2['value1'] 
[] 
Python2> id(dict2['value1']) 
43895336 
Python2> id(dict2['value2']) 
43895336 
Python2> id(dict2['value3']) 
43895336 

因此,您正在擴展相同的列表。

+0

我明白我爲什麼失敗得很清楚。謝謝! – 2011-03-12 10:41:37

0

正如其他人指出的那樣,問題在於您致電dict.fromkeys()會將對同一個空列表的引用與它在新字典中創建的每個鍵相關聯。一個簡單的解決方案是從collections模塊使dict2一個defaultdict類,使默認值爲單獨的新創建的空list

from collections import defaultdict 

dict1 = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'} 
dict2 = defaultdict(list) 

for key in dict1.itervalues(): 
    if key == 'value1': 
     dict2[key].extend(['test1', 'test2']) 
    elif key == 'value2': 
     dict2[key].extend(['test3', 'test4']) 
    elif key == 'value3': 
     dict2[key].extend(['test5', 'test6']) 

print dict2['value1'] 
# ['test1', 'test2'] 
print dict2['value3'] 
# ['test5', 'test6']