【问题标题】:Python sum on keys for List of Dictionaries [duplicate]字典列表键的Python总和[重复]
【发布时间】:2012-01-24 22:49:38
【问题描述】:

可能重复:
How to sum dict elements

我有一个字典列表如下:

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

我想对每个 name 求和 amt 并在 dict 列表中得到以下结果:

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

【问题讨论】:

  • 你做过什么(什么都做)吗?或者这是“制作我的代码”问题的另一种情况?
  • 如果它是重复的,最好提供指向重复问题的链接,而不是仅仅将其标记为重复

标签: python list dictionary


【解决方案1】:
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}]

【讨论】:

    【解决方案2】:

    另一种可能的解决方案,这次使用 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]
    

    【讨论】:

    • 我认为这个答案应该是公认的答案。
    • 正如 Martjin Pieters 曾经对我说的那样,使用 sorteditertools.groupby 可以实现单线,但由于额外的 sort 而引入了更多的复杂性/CPU 消耗
    【解决方案3】:
    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()]
    

    【讨论】:

      【解决方案4】:

      示例解决方案

      我不确定它是否“足够漂亮/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 }]

      完全按照要求 :)

      【讨论】:

        【解决方案5】:

        你可以这样做:

        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
        

        【讨论】:

        • 这几乎对我有用。谢谢
        猜你喜欢
        • 2019-01-16
        • 2013-09-21
        • 2021-02-08
        • 1970-01-01
        • 2021-01-16
        • 2013-05-22
        • 2020-08-09
        • 2019-02-05
        • 1970-01-01
        相关资源
        最近更新 更多