繁体   English   中英

字典列表:将具有相同值的数字相加

[英]List of dicts: Add up numbers with same values

我得到了以下字典列表

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},
            ]

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

先感谢您!

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

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()
]

一种使用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)

一个pandas的实现

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

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)

你可以用一个循环来完成它,在你第一次遇到产品时初始化它。

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}]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM