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

时间:2020-01-15 02:50:32

标签: python dictionary nested

我正在尝试计算具有相同子键的子字典的tot值。我有一个包含相关键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]

6 个答案:

答案 0 :(得分:4)

使用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})

尽管这些键可能具有比所需键更多的键,但是如果您的数据中有更多键。

答案 1 :(得分:1)

如果您希望将结果存储在字典中,则可以使用列表中的键创建一个并在其中计算结果。

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]

答案 2 :(得分:0)

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]

答案 3 :(得分:0)

尝试以下代码

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)

答案 4 :(得分:0)

您可以使用列表推导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,然后再提取数据。

答案 5 :(得分:0)

相同但不同。

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