You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何聚合含重复元素的Python字典列表并添加重复计数键?

合并聚合重复字典并添加计数字段

需要将包含重复元素的字典列表合并聚合,为每个字典新增QUANTITY键表示重复次数。

初始字典列表:

from decimal import Decimal

list_ = [
    {'id': 2, 'prodDescription': 'Hofbräu Kellerbier 500 ml', 'prodPrice': Decimal('6.50')}, 
    {'id': 1, 'prodDescription': 'Tonic Water 300 ml', 'prodPrice': Decimal('4.50')}, 
    {'id': 1, 'prodDescription': 'Tonic Water 300 ml', 'prodPrice': Decimal('4.50')}, 
    {'id': 3, 'prodDescription': 'Coxinha 6 unidades', 'prodPrice': Decimal('8.00')}]

期望结果:

list_ = [
    {'id': 2, 'prodDescription': 'Hofbräu Kellerbier 500 ml', 'prodPrice': Decimal('6.50'), 'QUANTITY': 1}, 
    {'id': 1, 'prodDescription': 'Tonic Water 300 ml', 'prodPrice': Decimal('4.50'), 'QUANTITY': 2}, 
    {'id': 3, 'prodDescription': 'Coxinha 6 unidades', 'prodPrice': Decimal('8.00'), 'QUANTITY': 1}]

错误尝试:使用collections.Counter时错误更新,导致结果为各键值的聚合总和:

from collections import Counter
from decimal import Decimal

list_ = [
    {'id': 2, 'prodDescription': 'Hofbräu Kellerbier 500 ml', 'prodPrice': Decimal('6.50')}, 
    {'id': 1, 'prodDescription': 'Tonic Water 300 ml', 'prodPrice': Decimal('4.50')}, 
    {'id': 1, 'prodDescription': 'Tonic Water 300 ml', 'prodPrice': Decimal('4.50')}, 
    {'id': 3, 'prodDescription': 'Coxinha 6 unidades', 'prodPrice': Decimal('8.00')}]

result = Counter()
for prod in list_:
    result.update(prod)
print(result)

错误输出:

Counter({'id': 7, 'prodDescription': 'Coxinha 6 unidadesTonic Water 300 mlTonic Water 300 mlHofbräu Kellerbier 500 ml', 'prodPrice': Decimal('23.50')})

问题原因

你之前的Counter.update(prod)用法错误:Counter.update接收字典时,会把字典的键作为统计元素,值作为该元素的计数增量。所以最终得到的是各键对应值的累加/拼接结果,而非整个字典的重复次数。


正确实现方法

方法1:用普通字典分组统计

核心思路是将每个字典转换为可哈希的类型(比如元组)作为键,统计重复次数,最后再将次数合并回原字典:

from decimal import Decimal

list_ = [
    {'id': 2, 'prodDescription': 'Hofbräu Kellerbier 500 ml', 'prodPrice': Decimal('6.50')}, 
    {'id': 1, 'prodDescription': 'Tonic Water 300 ml', 'prodPrice': Decimal('4.50')}, 
    {'id': 1, 'prodDescription': 'Tonic Water 300 ml', 'prodPrice': Decimal('4.50')}, 
    {'id': 3, 'prodDescription': 'Coxinha 6 unidades', 'prodPrice': Decimal('8.00')}]

# 用字典统计重复次数,键为可哈希的字典内容元组
count_dict = {}
for prod in list_:
    # 将字典转换为排序后的键值对元组(避免字典顺序影响)
    key = tuple(sorted(prod.items()))
    count_dict[key] = count_dict.get(key, 0) + 1

# 将统计结果转换为目标列表
result = []
for key, quantity in count_dict.items():
    prod = dict(key)
    prod['QUANTITY'] = quantity
    result.append(prod)

print(result)

方法2:用collections.defaultdict简化统计

和方法1逻辑一致,用defaultdict减少判断代码:

from collections import defaultdict
from decimal import Decimal

list_ = [
    {'id': 2, 'prodDescription': 'Hofbräu Kellerbier 500 ml', 'prodPrice': Decimal('6.50')}, 
    {'id': 1, 'prodDescription': 'Tonic Water 300 ml', 'prodPrice': Decimal('4.50')}, 
    {'id': 1, 'prodDescription': 'Tonic Water 300 ml', 'prodPrice': Decimal('4.50')}, 
    {'id': 3, 'prodDescription': 'Coxinha 6 unidades', 'prodPrice': Decimal('8.00')}]

count_dict = defaultdict(int)
for prod in list_:
    key = tuple(sorted(prod.items()))
    count_dict[key] += 1

# 用字典合并运算符简化转换
result = [dict(key) | {'QUANTITY': qty} for key, qty in count_dict.items()]
print(result)

方法3:用collections.Counter正确统计

需要将每个字典转成可哈希的类型作为Counter的统计元素:

from collections import Counter
from decimal import Decimal

list_ = [
    {'id': 2, 'prodDescription': 'Hofbräu Kellerbier 500 ml', 'prodPrice': Decimal('6.50')}, 
    {'id': 1, 'prodDescription': 'Tonic Water 300 ml', 'prodPrice': Decimal('4.50')}, 
    {'id': 1, 'prodDescription': 'Tonic Water 300 ml', 'prodPrice': Decimal('4.50')}, 
    {'id': 3, 'prodDescription': 'Coxinha 6 unidades', 'prodPrice': Decimal('8.00')}]

# 转换为可哈希的元组列表,再用Counter统计
counter = Counter(tuple(sorted(prod.items())) for prod in list_)

result = [dict(key) | {'QUANTITY': count} for key, count in counter.items()]
print(result)

内容的提问来源于stack exchange,提问作者Eduardo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 00:45:13