Python列表中字典键的总和

10

可能是重复问题:
如何对字典元素求和

我有一个如下的字典列表:

[{'Name': 'A', 'amt':100},
 {'Name': 'B', 'amt':200},
 {'Name': 'A', 'amt':300},
 {'Name': 'C', 'amt':400},
 {'Name': 'C', 'amt':500},
 {'Name': 'A', 'amt':600}]
我想为每个名字的amt求和,并在字典列表中得到以下结果:
 [{'Name':'A', 'amt':1000},
  {'Name':'B', 'amt':200},
  {'Name':'C', 'amt':900}]

2
你做了什么(任何事情)吗?还是这又是一个“帮我写代码”的问题? - juliomalegria
1
如果这是一个重复的问题,给出重复问题的链接而不仅仅标记为重复将会更好。 - Gabe
5个回答

19
from collections import defaultdict

c = defaultdict(int)
for d in list_of_dictionaries:
    c[d['Name']] += d['amt']

它产生了c

{'A': 1000, 'C': 900, 'B': 200}
将其转换为字典列表:
[{'Name': name, 'amt': amt} for name, amt in c.items()]

结果:

[{'Name': 'A', 'amt': 1000}, {'Name': 'C', 'amt': 900}, {'Name': 'B', 'amt':200}]

7

另一个可能的解决方案,这次使用itertools:

lst = [
{'Name': 'A', 'amt':100},
{'Name': 'B', 'amt':200},
{'Name': 'A', 'amt':300},
{'Name': 'C', 'amt':400},
{'Name': 'C', 'amt':500},
{'Name': 'A', 'amt':600}]

import itertools as it
keyfunc = lambda x: x['Name']

groups = it.groupby(sorted(lst, key=keyfunc), keyfunc)
[{'Name':k, 'amt':sum(x['amt'] for x in g)} for k, g in groups]

1
我认为这个答案应该被接受。 - Menglong Li
1
正如Martjin Pieters曾经对我说的那样,使用sorteditertools.groupby可以实现一行代码,但由于额外的sort操作会增加一些复杂性和CPU消耗。 - Jean-François Fabre

2
output_dict = {}
for i in dict_list:
    if i['Name'] in output_dict:
        output_dict[i['Name']] = i['amt']
    else:
        output_dict[i['Name']] += i['amt']

我会为你提供一个字典,其中键是名称,值是金额。如果你必须将其作为字典列表:

[{'Name':key, 'amt':value} for key, value in output_dict.items()]

2

示例解决方案

我不确定它是否“足够美观/Pythonic”,但它确实很短,并且不需要额外的模块即可运行

def get_amt(name):
    return lambda x: x['amt'] if x['Name']==name else 0

names = sorted(set(map(lambda x: x['Name'], data)))
result = [{'Name':name,'amt':sum(map(get_amt(name), data))} for name in names]

证明

证明在这里:http://codepad.org/L1gcTpVK

如果您按照问题中提供的data,则result将等于以下内容:

[{'Name': 'A', 'amt': 1000}, {'Name': 'B', 'amt': 200}, {'Name': 'C', 'amt': 900}]

这正是所要求的结果 :)


0

你可以这样做:

def sum(dict_list):
    result_list = []
    name_dict = {}
    for dict_item in dict_list:
        name = dict_item['Name']
        amt = dict_item['amt']
        if name_dict.has_key(name):
            pos = name_dict[name]
            result_list[pos] = {'Name':name, 'amt': (result_list[pos]['amt']+amt)}
        else:
            result_list.append(dict_item)
            name_dict[name] = len(result_list) - 1
    return result_list

这个对我来说几乎就是原封不动的。谢谢。 - Erich

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接