合并字典而不覆盖其中值为列表的先前值

时间:2013-12-11 02:42:01

标签: python dictionary merge

我知道Merge dictionaries without overwriting valuesmerging "several" python dictionariesHow to merge multiple dicts with same key?How to merge two Python dictionaries in a single expression?

然而,我的问题略有不同。

假设我有这三本词典

dict_a = {'a': [3.212], 'b': [0.0]}
dict_b = {'a': [923.22, 3.212], 'c': [123.32]}
dict_c = {'b': [0.0]}

合并后的结果应为

result_dict = {'a': [3.212, 3.212, 923.22], 'b': [0.0, 0.0], 'c': [123.32]}

这里的代码可行,但会在列表中嵌套列表

result_dict = {}
dicts = [dict_a, dict_b, dict_c]

for d in dicts:
    for k, v in d.iteritems():
        result_dict.setdefault(k, []).append(v)

使用extend代替append会阻止嵌套列表,但如果密钥尚不存在则无效。所以基本上它应该在没有覆盖的情况下执行update,就像在其他线程中一样。

对不起,这是我的错误。昨天为时已太晚了,我没有注意到犯错误的行不是我认为的错误,因此假设我的词典已经具有上述结构。 事实上,mgilson是正确的,假设它与TypeError相关。确切地说,是一个“无法浮动的”。

1 个答案:

答案 0 :(得分:3)

我很确定.extend在这里工作......

>>> dict_a = {'a': [3.212], 'b': [0.0]}
>>> dict_b = {'a': [923.22, 3.212], 'c': [123.32]}
>>> dict_c = {'b': [0.0]}
>>> result_dict = {}
>>> dicts = [dict_a, dict_b, dict_c]
>>> 
>>> for d in dicts:
...     for k, v in d.iteritems():
...         result_dict.setdefault(k, []).extend(v)
... 
>>> result_dict
{'a': [3.212, 923.22, 3.212], 'c': [123.32], 'b': [0.0, 0.0]}

神奇的是dict.setdefault方法。如果该密钥不存在,setdefault 会添加一个具有您提供的默认值的新密钥。然后返回该默认值,然后可以对其进行修改。


请注意,如果项v不可迭代,则此解决方案将出现问题。也许这就是你的意思?例如如果dict_a = {'a': [3.212], 'b': 0.0}

在这种情况下,我认为你需要在TypeError: type object is not iterable条款中使用try-except

for d in dicts:
    for k, v in d.iteritems():
        try:
            result_dict.setdefault(k, []).extend(v)
        except TypeError:
            result_dict[k].append(v)