【问题标题】:Group and sum list of dictionaries by parameter按参数分组和汇总字典列表
【发布时间】:2019-05-26 17:31:21
【问题描述】:

我有我的产品(饮料、食品等)的字典列表,其中一些产品可能会被添加多次。我需要按 product_id 参数对我的产品进行分组,并将每个组的 product_cost 和 product_quantity 相加,以获得产品总价。

我是python的新手,了解如何对字典列表进行分组,但不知道如何对一些参数值求和。

"products_list": [
    {
        "product_cost": 25,
        "product_id": 1,
        "product_name": "Coca-cola",
        "product_quantity": 14,
    },
    {
        "product_cost": 176.74,
        "product_id": 2,
        "product_name": "Apples",
        "product_quantity": 800,

    },
    {
        "product_cost": 13,
        "product_id": 1,
        "product_name": "Coca-cola",
        "product_quantity": 7,
    }
]

我需要实现这样的目标:

"products_list": [
    {
        "product_cost": 38,
        "product_id": 1,
        "product_name": "Coca-cola",
        "product_quantity": 21,
    },
    {
        "product_cost": 176.74,
        "product_id": 2,
        "product_name": "Apples",
        "product_quantity": 800,

    }
]

【问题讨论】:

  • 你能提供你已经尝试过的吗?
  • 仅通过在循环中附加到 defaultdict 进行分组
  • 您能否提供您已经尝试过的内容,还请在下面查看我的答案,我使用与您相同的方法完成@NatalyFirstova

标签: python json list dictionary grouping


【解决方案1】:

您可以先在product_name 上对字典列表进行排序,然后根据product_name 对项目进行分组

然后对于每个组,计算总产品和总数量,创建你的最终字典并更新到列表,然后制作你的最终字典

from itertools import groupby

dct = {"products_list": [
    {
        "product_cost": 25,
        "product_id": 1,
        "product_name": "Coca-cola",
        "product_quantity": 14,
    },
    {
        "product_cost": 176.74,
        "product_id": 2,
        "product_name": "Apples",
        "product_quantity": 800,

    },
    {
        "product_cost": 13,
        "product_id": 1,
        "product_name": "Coca-cola",
        "product_quantity": 7,
    }
]}

result = {}
li = []

#Sort product list on product_name
sorted_prod_list = sorted(dct['products_list'], key=lambda x:x['product_name'])

#Group on product_name
for model, group in groupby(sorted_prod_list,key=lambda x:x['product_name']):

    grp = list(group)

    #Compute total cost and qty, make the dictionary and add to list
    total_cost = sum(item['product_cost'] for item in grp)
    total_qty = sum(item['product_quantity'] for item in grp)
    product_name = grp[0]['product_name']
    product_id = grp[0]['product_id']

    li.append({'product_name': product_name, 'product_id': product_id, 'product_cost': total_cost, 'product_quantity': total_qty})

#Make final dictionary
result['products_list'] = li

print(result)

输出将是

{
    'products_list': [{
            'product_name': 'Apples',
            'product_id': 2,
            'product_cost': 176.74,
            'product_quantity': 800
        },
        {
            'product_name': 'Coca-cola',
            'product_id': 1,
            'product_cost': 38,
            'product_quantity': 21
        }
    ]
}

【讨论】:

    【解决方案2】:

    你可以试试 pandas:

    d = {"products_list": [
        {
            "product_cost": 25,
            "product_id": 1,
            "product_name": "Coca-cola",
            "product_quantity": 14,
        },
        {
            "product_cost": 176.74,
            "product_id": 2,
            "product_name": "Apples",
            "product_quantity": 800,
    
        },
        {
            "product_cost": 13,
            "product_id": 1,
            "product_name": "Coca-cola",
            "product_quantity": 7,
        }
    ]}
    
    df=pd.DataFrame(d["products_list"])
    

    将 dict 传递给 pandas 并执行 groupby。 然后用 to_dict 函数将其转换回dict。

    result={}
    result["products_list"]=df.groupby("product_name",as_index=False).sum().to_dict(orient="records")
    

    结果:

    {'products_list': [{'product_cost': 176.74,
       'product_id': 2,
       'product_name': 'Apples',
       'product_quantity': 800},
      {'product_cost': 38.0,
       'product_id': 2,
       'product_name': 'Coca-cola',
       'product_quantity': 21}]}
    

    【讨论】:

      【解决方案3】:

      就我个人而言,我会通过唯一标识符将其重新组织到另一个字典中。此外,如果您仍然需要列表格式的它,您仍然可以在字典中重新组织它,但您可以将 dict.values() 转换为列表。下面是一个执行此操作的函数。

      def get_totals(product_dict):
          totals = {}
          for product in product_list["product_list"]:
              if product["product_name"]  not in totals:
                  totals[product["product_name"]] = product
              else:
      
                  totals[product["product_name"]]["product_cost"] += product["product_cost"]
                  totals[product["product_name"]]["product_quantity"] += product["product_quantity"]
      
          return list(totals.values())
      

      输出是:

      [
       {
        'product_cost': 38,
        'product_id': 1,
        'product_name': 'Coca-cola', 
        'product_quantity': 21
       },
       {
        'product_cost': 176.74,
        'product_id': 2, 
        'product_name': 'Apples',
        'product_quantity': 800
       }
      ]
      

      现在,如果您需要它属于产品列表键。只需将列表重新分配给相同的键。而不是返回list(total.values())

      product_dict["product_list"] = list(total.values())
      return product_dict
      

      输出是一个像这样的字典:

      {
       "products_list": [
         {
          "product_cost": 38,
          "product_id": 1,
          "product_name": "Coca-cola",
          "product_quantity": 21,
         },
         {
          "product_cost": 176.74,
          "product_id": 2,
          "product_name": "Apples",
          "product_quantity": 800,
      
         }
       ]
      }
      

      【讨论】:

        猜你喜欢
        • 2021-05-11
        • 2014-03-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多