繁体   English   中英

将嵌套字典中相同键的值相加

[英]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)

~

您可以使用列表推导式、 zipmap来完成此操作。 首先,我们要从每个子字典中提取相应的值:

>>> 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM