Python:如何在for循环中交替修改字典值和键?

4

我刚开始学习Python(以及编程)。

我想通过在for循环中交替更改字典的键来修改字典。然而,我写的以下代码没有成功:

#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"从另一个字典创建字典,但即使是这种情况,我也看不出有什么问题。

感谢您的关注。期待您的建议。

5个回答

7
所有的dict2值实际上都是同一个列表实例,因为将[]传递给dict.fromkeys()只会创建一个列表实例。请尝试:
dict2 = {v: [] for v in dict1.values()}

我得到了我期望的结果,也明白了我错过的地方。谢谢! - miyazaki_tara
@miyazaki_tara:如果你认为这个答案最好,那么你应该接受它。 - martineau
这里有文档记录:https://docs.python.org/3/library/stdtypes.html#:~:text=所有的值都指向同一个实例,因此通常不应该将值设为可变对象,比如空列表。如果要获取不同的值,请使用字典推导式。 - dgor

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
问题在于dict.fromkeys()使用相同的对象初始化每个项目。
dict2 = dict((x, []) for x in dict1.values())

谢谢!我现在明白我错过了什么。 - miyazaki_tara

0

正如其他人指出的那样,问题在于你对 dict.fromkeys() 的调用将一个对同一空列表的引用与创建在新字典中的每个键相关联。一个简单的解决方案是将 dict2 设为来自 collections 模块的 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']

0

遍历 yourdict.keys()(这将返回一个列表,因此不会受到对字典的任何更改的影响)


循环内部仅修改字典值,这是可以的。 - Sven Marnach

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接