我想将字典的值添加到另一个字典中。例如:
adict = {1: {'a': 13, 'b': 19, 'c': 15}, 2: {'a': 7, 'b': 2, 'c': 0}}
如果我们将{1: {'a': 3, 'b': 9, 'c': 23}}
添加到adict
然后adict应该是:
{1: {'a': 16, 'b': 28, 'c': 38}, 2: {'a': 7, 'b': 2, 'c': 0}}
如果我们添加{3: {'a': 4}}
,那么adict现在应该是:
{1: {'a': 16, 'b': 28, 'c': 38}, 2: {'a': 7, 'b': 2, 'c': 0}, 3: {'a': 4}}
如果我们添加{2: {'a': 1, 'b': 8, 'c': 27, 'd': 11}}
然后adict应该是:
{1: {'a': 16, 'b': 28, 'c': 38}, 2: {'a': 8, 'b': 10, 'c': 27, 'd': 11}, 3: {'a': 4}}
最好的方法是什么?
答案 0 :(得分:6)
简单的递归函数:
>>> adict = {1: {'a': 13, 'b': 19, 'c':15}, 2: {'a': 7, 'b': 2, 'c':0}}
>>> def dict_add(a,b):
... a = a.copy()
... for k,v in b.items():
... if isinstance(v,(dict,)):
... a[k] = dict_add(a.get(k,{}),v)
... else:
... a[k] = a.get(k,0) + v
... return a
...
>>> dict_add(adict,{1: {'a': 3, 'b': 9, 'c': 23}})
{1: {'a': 16, 'c': 38, 'b': 28}, 2: {'a': 7, 'c': 0, 'b': 2}}
>>> dict_add(dict_add(adict,{1: {'a': 3, 'b': 9, 'c': 23}}),{3:{'a':4}})
{1: {'a': 16, 'c': 38, 'b': 28}, 2: {'a': 7, 'c': 0, 'b': 2}, 3: {'a': 4}}
答案 1 :(得分:3)
这可能非常低效,但这就是我提出的:
def dict_add(a, b):
result = dict(a)
for key, value in b.items():
if type(value) != dict:
result[key] = result.get(key, 0) + value
else:
result[key] = dict_add(result.get(key, {}), value)
return result
运行此代码会产生以下结果:
>>> adict = {1: {'a': 13, 'b': 19, 'c':15}, 2: {'a': 7, 'b': 2, 'c':0}}
>>> bdict = {1: {'a': 3, 'b': 9, 'c': 23}}
>>>
>>> print dict_add(adict, bdict)
{1: {'a': 16, 'c': 38, 'b': 28}, 2: {'a': 7, 'c': 0, 'b': 2}}
答案 2 :(得分:0)
这是一个功能性解决方案。 rec_add
函数可以使用任意嵌套的字典执行您的操作。
def combine(f, d1, d2):
"""Create a new dict combining d1 and d2.
Keys appearing only in one of the input dict are copied unmodified. Values
with matching keys are combined using f and copied in the output dict."""
keys = set(d1.keys() + d2.keys())
out = { }
for key in keys:
if key in d1:
if key in d2:
out[key] = f(d1[key], d2[key])
else:
out[key] = d1[key]
else:
out[key] = d2[key]
return out
def rec_combine(f, d1, d2):
"""Recursively combine all dicts."""
def aux(v1, v2):
if isinstance(v1, (dict,)) and isinstance(v2, (dict,)):
return rec_combine(f, v1, v2)
else:
return f(v1, v2)
return combine(aux, d1, d2)
def rec_add(d1, d2):
"""Recursively sum values in d1 and d2."""
return rec_combine(lambda x, y: x + y, d1, d2)