Группировать и суммировать список словарей по параметрам - PullRequest
1 голос
/ 26 мая 2019

У меня есть список словарей моих продуктов (напитки, еда и т. Д.), Некоторые из продуктов могут быть добавлены несколько раз. Мне нужно сгруппировать свои продукты по параметру 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,

    }
]

Ответы [ 3 ]

1 голос
/ 26 мая 2019

Вы можете начать с сортировки списка словарей по 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
        }
    ]
}
1 голос
/ 26 мая 2019

Я лично реорганизовал бы его в другой словарь по уникальным идентификаторам.Кроме того, если вам все еще нужно это в формате списка, вы все равно можете реорганизовать его в словарь, но вы можете просто преобразовать 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()) do

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,

   }
 ]
}
1 голос
/ 26 мая 2019

Вы можете попробовать с пандами:

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 пандам и выполните групповую игру. Затем преобразуйте его обратно в dict с помощью функции to_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}]}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...