[英]Summing values in dictionary of dictionaries
I got something like this: 我有这样的事情:
> d1 = {'System tests': {'failed': 5, 'passed': 0, 'total': 5},
'Func tests': {'failed': 5, 'passed': 0, 'total': 5}}
> d2 = {'System tests': {'failed': 1, 'passed': 1, 'total': 2},
'Func tests': {'failed': 3, 'passed': 2, 'total': 5}}
> d3 = {'System tests': {'failed': 0, 'passed': 0, 'total': 0},
'Func tests': {'failed': 1, 'passed': 0, 'total': 1}}
I would like to sum values 'failed', passed and total into one dictionary 我想将值'失败',传递和总和加到一个字典中
so the output should be like this: 所以输出应该是这样的:
d4 = {'System tests': {'failed': 6, 'passed': 1, 'total': 7},
'Func tests': {'failed': 9, 'passed': 2, 'total': 11}
What is the easiest solution to do such thing? 做这种事最简单的解决办法是什么?
I can use basic libraries, except collections. 我可以使用基本库,除了集合。
The solution must be generic, for example if some other dictionaries would appear in the future 解决方案必须是通用的,例如,如果将来出现其他一些字典
input: 输入:
d1 = {'a': 100, 'b': 200, 'c':300}
d2 = {'a': 300, 'b': 200, 'd':400}
d = {k : d1.get(k, 0) + d2.get(k,0) for k in set(d1.keys()) | set(d2.keys())}
Output: 输出:
{'a': 400, 'b': 400, 'c': 300, 'd': 400}
Using Counter
and defaultdict
that is fairly straight forward like: 使用相当简单的
Counter
和defaultdict
,如:
d4 = defaultdict(Counter)
for d in d1, d2, d3:
for k, subd in d.items():
d4[k].update(subd)
d1 = {'System tests': {'failed': 5, 'passed': 0, 'total': 5},
'Func tests': {'failed': 5, 'passed': 0, 'total': 5}}
d2 = {'System tests': {'failed': 1, 'passed': 1, 'total': 2},
'Func tests': {'failed': 3, 'passed': 2, 'total': 5}}
d3 = {'System tests': {'failed': 0, 'passed': 0, 'total': 0},
'Func tests': {'failed': 1, 'passed': 0, 'total': 1}}
from collections import Counter, defaultdict
d4 = defaultdict(Counter)
for d in d1, d2, d3:
for k, subd in d.items():
d4[k].update(subd)
print(d4)
defaultdict(<class 'collections.Counter'>, {
'System tests': Counter({'total': 7, 'failed': 6, 'passed': 1}),
'Func tests': Counter({'total': 11, 'failed': 9, 'passed': 2})
})
This will give you the output you are looking for, with no libraries. 这将为您提供您正在寻找的输出,没有库。
d4 = {}
for d in d1, d2, d3:
for test, results in d.items():
if test not in d4:
d4[test] = {}
for key, value in results.items():
if key in d4[test]:
d4[test][key] += value
else:
d4[test][key] = value
Result: 结果:
{'System tests': {'failed': 6, 'passed': 1, 'total': 7}, 'Func tests': {'failed': 9, 'passed': 2, 'total': 11}}
If you cannot use collections.Counter
, another solution is to use reduce
如果你不能使用
collections.Counter
,另一种解决方案是使用reduce
from functools import reduce # reduce was moved here in Python3
def add_dicts(dict_list):
def add(fst, snd):
return {k: fst[k] + snd[k] for k in fst}
return reduce(add, dict_list[1:], dict_list[0])
Using this in your code would look like this. 在代码中使用它看起来像这样。
dict_list = [d1, d2, d3]
d4 = {}
for k in dict_list[0]:
d4[k] = add_dicts([d[k] for d in dict_list])
Although, this assumes all your dict
are correctly formated. 虽然,这假设您的所有
dict
都正确格式化。
You can use zip
along with dict.items
: 您可以将
zip
与dict.items
一起使用:
d1 = {'System tests': {'failed': 5, 'passed': 0, 'total': 5},
'Func tests': {'failed': 5, 'passed': 0, 'total': 5}}
d2 = {'System tests': {'failed': 1, 'passed': 1, 'total': 2},
'Func tests': {'failed': 3, 'passed': 2, 'total': 5}}
d3 = {'System tests': {'failed': 0, 'passed': 0, 'total': 0},
'Func tests': {'failed': 1, 'passed': 0, 'total': 1}}
def combine_dicts(*d):
return {a:{i:sum(h[i] for h in [b, c, d]) for i in ['failed', 'passed', 'total']} for [a, b], [_, c], [_, d] in zip(*d)}
print(combine_dicts(d1.items(), d2.items(), d3.items()))
Output: 输出:
{'System tests': {'failed': 6, 'total': 7, 'passed': 1}, 'Func tests': {'failed': 9, 'total': 11, 'passed': 2}}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.