【问题标题】:List of dicts: Add up numbers with same values字典列表:将具有相同值的数字相加
【发布时间】:2021-10-11 10:35:33
【问题描述】:

我得到了以下字典列表

list_of_dicts = [
                {'product': 'car', 'city': 'new york', 'quantity': 13},
                {'product': 'car', 'city': 'new york', 'quantity': 25},
                {'product': 'bus', 'city': 'miami', 'quantity': 5},
                {'product': 'container', 'city': 'atlanta', 'quantity' 5},
                {'product': 'container', 'city': 'atlanta', 'quantity' 8}
            ]

我的目标是,当“产品”和“城市”的值相同时,将“数量”的值相加。 结果应如下所示:

result_list_of_dicts = [
                {'product': 'car', 'city': 'new york', 'quantity': 38},
                {'product': 'bus', 'city': 'miami', 'quantity': 5},
                {'product': 'container', 'city': 'atlanta', 'quantity' 13},
            ]

有pythonic的方式吗?我尝试了一些东西,但我最好不要展示它们,因为它们真的很丑。

提前谢谢你!

【问题讨论】:

  • 无论外观如何,您能否发布您的尝试?
  • 你在尝试什么? ,你有一些代码吗?
  • 您是否仅限于 python 内置模块或是否允许使用外部模块,如 numpypandas
  • 是的,pandas 和 numpy 都没有问题
  • 您是否有充分的理由将这些数据存储为字典而不仅仅是列表?

标签: python


【解决方案1】:

您可以仅使用标准库实用程序执行以下操作:

from operator import itemgetter
from functools import reduce
from itertools import groupby

pc = itemgetter("product", "city")  # sorting and grouping key
q = itemgetter("quantity")
combine = lambda d1, d2: {**d1, "quantity": q(d1) + q(d2)}

[reduce(combine, g) for _, g in groupby(sorted(list_of_dicts, key=pc), key=pc)]
# [{'product': 'bus', 'city': 'miami', 'quantity': 5}, 
#  {'product': 'car', 'city': 'new york', 'quantity': 38}, 
#  {'product': 'container', 'city': 'atlanta', 'quantity': 13}]

或者,也许更简单和线性:

from collections import Counter

pc = itemgetter("product", "city") 
q = itemgetter("quantity")

totals = Counter()
for dct in list_of_dicts:
    totals[pc(dct)] += q(dct)

result_list_of_dicts = [
    {"product": p, "city": c, "quantity": q} for (p, c), q in totals.items()
]

【讨论】:

  • 好的,太棒了!非常感谢!!
【解决方案2】:

一种使用collections.Counter的方法

from collections import Counter

list_of_dicts = [
    {'product': 'car', 'city': 'new york', 'quantity': 13},
    {'product': 'car', 'city': 'new york', 'quantity': 25},
    {'product': 'bus', 'city': 'miami', 'quantity': 5},
    {'product': 'container', 'city': 'atlanta', 'quantity': 5},
    {'product': 'container', 'city': 'atlanta', 'quantity': 8}
]

counts = sum((Counter({(d["product"], d["city"]): d["quantity"]}) for d in list_of_dicts), Counter())
result = [{"product": product, "city": city, "quantity": quantity} for (product, city), quantity in counts.items()]
print(result)

【讨论】:

    【解决方案3】:

    熊猫实现

    按“产品”和“城市”分组,对组求和并重置索引以获得原始列。

    import pandas as pd
    
    list_of_dicts = [
        {'product': 'car', 'city': 'new york', 'quantity': 13},
        {'product': 'car', 'city': 'new york', 'quantity': 25},
        {'product': 'bus', 'city': 'miami', 'quantity': 5},
        {'product': 'container', 'city': 'atlanta', 'quantity': 5},
        {'product': 'container', 'city': 'atlanta', 'quantity': 8}
    ]
    
    df = pd.DataFrame(list_of_dicts)
    print(df)
    df = df.groupby(["product", "city"]).sum().reset_index()
    print(df)
    summed_dict = df.to_dict("records")
    print(summed_dict)
    

    【讨论】:

      【解决方案4】:

      您可以使用循环来执行此操作,在您第一次遇到产品时对其进行初始化。

      list_of_dicts = [
          {'product': 'car', 'city': 'new york', 'quantity': 13},
          {'product': 'car', 'city': 'new york', 'quantity': 25},
          {'product': 'bus', 'city': 'miami', 'quantity': 5},
          {'product': 'container', 'city': 'atlanta', 'quantity': 5},
          {'product': 'container', 'city': 'atlanta', 'quantity': 8}
      ]
      
      new_dict = {}
      for ld in list_of_dicts:
          if ld['product'] not in new_dict:
              new_dict[ld['product']] = {}
              new_dict[ld['product']]['city'] = ld['city']
              new_dict[ld['product']]['quantity'] = 0
          new_dict[ld['product']]['quantity'] += ld['quantity']
      
      # print(new_dict)
      # {'car': {'city': 'new york', 'quantity': 38}, 'bus': {'city': 'miami', 'quantity': 5}, 'container': {'city': 'atlanta', 'quantity': 13}}
      
      result_list_of_dicts = [{'product': nd,
                               'city': new_dict[nd]['city'],
                               'quantity': new_dict[nd]['quantity']} for nd in new_dict]
      # print(result_list_of_dicts)
      # [{'product': 'car', 'city': 'new york', 'quantity': 38}, {'product': 'bus', 'city': 'miami', 'quantity': 5}, {'product': 'container', 'city': 'atlanta', 'quantity': 13}]
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-07-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-28
        • 2019-12-26
        • 1970-01-01
        相关资源
        最近更新 更多