如何在Python中减少/聚合每个密钥列表的列表? [英] How to reduce/aggregate a list of dicts per multiple keys in Python?

查看:101
本文介绍了如何在Python中减少/聚合每个密钥列表的列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的类似列表:

sales_per_store_per_day = [
   {'date':'2014-06-01', 'store':'a', 'product1':10, 'product2':3, 'product3':15},
   {'date':'2014-06-01', 'store':'b', 'product1':20, 'product2':4, 'product3':16},
   {'date':'2014-06-02', 'store':'a', 'product1':30, 'product2':5, 'product3':17},
   {'date':'2014-06-02', 'store':'b', 'product1':40, 'product2':6, 'product3':18},
]

我可以减少这个列表,为每个商店提供一个产品,忽略日期吗?上述输入的结果是:

How could I reduce this list to have a sum of products for each store, ignoring the date? The result for the above input would be:

sales_per_store = [
   {'store':'a', 'product1':40, 'product2':8, 'product3':32},
   {'store':'b', 'product1':60, 'product2':10, 'product3':34}
]


推荐答案

使用 collections.defaultdict() 跟踪每个商店的信息,以及 collections.Counter( ) 以减少数字的总和:

Use a collections.defaultdict() to track info per store, and collections.Counter() to ease summing of the numbers:

from collections import defaultdict, Counter

by_store = defaultdict(Counter)

for info in sales_per_store_per_day:
    counts = Counter({k: v for k, v in info.items() if k not in ('store', 'date')})
    by_store[info['store']] += counts

sales_per_store = [dict(v, store=k) for k, v in by_store.items()]

计数是一个 Counter()信息字典;我假设除存储日期之外的所有内容都是产品数量。它使用字母理解产生一个复制,并删除这两个键。 by_store [info ['store']] 查找给定商店的当前总计数(默认为新的,空的 Counter() 对象)。

counts is a Counter() instance built from each of the products in the info dictionary; I'm assuming that everything except the store and date keys are product counts. It uses a dict comprehension to produce a copy with those two keys removed. The by_store[info['store']] looks up the current total counts for the given store (which default to a new, empty Counter() object).

最后一行然后生成所需的输出;新的字典与'store'和每个产品计数,但您可能希望将商店中的字典映射保存到 Counter 对象

The last line then produces your desired output; new dictionaries with 'store' and per-product counts, but you may want to just keep the dictionary mapping from store to Counter objects.

演示:

>>> from collections import defaultdict, Counter
>>> sales_per_store_per_day = [
...    {'date':'2014-06-01', 'store':'a', 'product1':10, 'product2':3, 'product3':15},
...    {'date':'2014-06-01', 'store':'b', 'product1':20, 'product2':4, 'product3':16},
...    {'date':'2014-06-02', 'store':'a', 'product1':30, 'product2':5, 'product3':17},
...    {'date':'2014-06-02', 'store':'b', 'product1':40, 'product2':6, 'product3':18},
... ]
>>> by_store = defaultdict(Counter)
>>> for info in sales_per_store_per_day:
...     counts = Counter({k: v for k, v in info.items() if k not in ('store', 'date')})
...     by_store[info['store']] += counts
... 
>>> [dict(v, store=k) for k, v in by_store.items()]
[{'store': 'a', 'product3': 32, 'product2': 8, 'product1': 40}, {'store': 'b', 'product3': 34, 'product2': 10, 'product1': 60}]

这篇关于如何在Python中减少/聚合每个密钥列表的列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆