![](/img/trans.png)
[英]Add up values of same key in nested dictionary where keys are elements of a list
[英]Add up values of same key in a nested dictionary
我正在尝试计算具有相同子键的子词典的总数值。 我有一个包含相关键mylist
的列表,我只需要计算列表中每个元素的值的总和。
mylist = ['age','answ1', 'answ2', 'answ3']
d = {'01': {'age':19, 'answ1':3, 'answ2':7, 'answ3':2}, '02': {'age':52, 'answ1':8, 'answ2':1, 'answ3':10},...}
我试过了
tot = []
for k,v in d.items():
for ke, va in v.items():
for i in mylist[0:]
count=0
if ke == i:
count+=v[ke]
tot.append(count)
但不是具有相同键的值的总和,而是按照字典中出现的顺序获取不同键的值。 预期的结果是
tot = [71, 11, 8, 12]
我得到的是
tot = [19, 3, 7, 2, 52, 8, 1, 10]
使用collections.Counter
:
>>> ctr = sum(map(Counter, d.values()), Counter())
>>> [ctr[x] for x in mylist]
[71, 11, 8, 12]
或者:
>>> [sum(e[k] for e in d.values()) for k in mylist]
[71, 11, 8, 12]
如果某些子字典可能缺少键,只需使用e.get(k, 0)
。 Counter
解决方案不需要它,它默认提供零。
嗯,既然你现在接受了一个dict
结果解决方案......
>>> dict(sum(map(Counter, d.values()), Counter()))
{'age': 71, 'answ1': 11, 'answ2': 8, 'answ3': 12}
或者也许只是
>>> sum(map(Counter, d.values()), Counter())
Counter({'age': 71, 'answ3': 12, 'answ1': 11, 'answ2': 8})
尽管这些键可能比所需的键更多,但如果您的数据中有更多键。
如果您希望将结果存储在字典中,您可以使用列表中的键创建一个并在那里计算结果。
result = {i: 0 for i in mylist}
for k, v in d.items():
result['age'] += v['age']
result['answ1'] += v['answ1']
result['answ2'] += v['answ2']
result['answ3'] += v['answ3']
result
{'age': 71, 'answ1': 11, 'answ2': 8, 'answ3': 12}
然而,这确实依赖于不改变的键,顺序应该无关紧要。
编辑
无论键名如何,您都可以通过以下更新执行此操作。 请注意,它增加了一个额外的迭代。
result = {i: 0 for i in mylist}
for k, v in d.items():
for ke, va in v.items():
result[ke] += v[ke]
mylist = ['age','answ1', 'answ2', 'answ3']
d = {'01': {'age':19, 'answ1':3, 'answ2':7, 'answ3':2}, '02': {'age':52, 'answ1':8, 'answ2':1, 'answ3':10}}
tot = [0] * len(mylist)
for k in d:
for idx, i in enumerate(mylist):
tot[idx] += d[k].get(i, 0)
print(tot)
印刷:
[71, 11, 8, 12]
试试下面的代码
for i in mylist:
count=0
for k,v in d.items():
for ke, va in v.items():
if ke == i:
count+=va
tot.append(count)
~
您可以使用列表推导式、 zip
和map
来完成此操作。 首先,我们要从每个子字典中提取相应的值:
>>> vals = [[v[k] for k in mylist] for v in d.values()]
>>> vals
[[19, 3, 7, 2], [52, 8, 1, 10]]
现在我们要对所有子列表执行元素求和:
>>> result = map(sum, zip(*vals))
>>> list(result)
[71, 11, 8, 12]
将所有内容放在一行中:
>>> result = map(sum, zip(*([v[k] for k in mylist] for v in d.values())))
>>> list(result)
[71, 11, 8, 12]
这种方法的好处是只访问我们想要构建的键,而不是构建一个完整的Counter
,然后再提取数据。
同样的事情,但不同。
>>> import operator
>>> f = operator.itemgetter(*mylist)
>>> vals = map(f,d.values())
>>> sums = map(sum,zip(*vals))
>>> result = dict(zip(mylist,sums))
>>> result
{'age': 71, 'answ1': 11, 'answ2': 8, 'answ3': 12}
如果您不想要字典,请跳过它并使用result = list(sums)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.