2011-03-12 48 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']