如何对字典列表按plate分组求和distance与time字段值?
按车牌分组汇总多字段的优化实现方案
需求说明
按车牌(plate)分组,汇总对应车辆的行驶距离(distance)与行驶时间(time),原始实现功能正常但存在代码冗余、效率可优化的问题。
原始代码与结果
原始实现代码:
# plate: license plate of the vehicule # distance: the distance traveled by the vehicule in KM # time: the time the vehicule travels in minutes from collections import defaultdict vehicles = [ {"plate":"ABC123", "distance":80.3, "time":180}, {"plate":"ABC123", "distance":80.3, "time":180}, {"plate":"XYZ246", "distance":40.0, "time":30}, {"plate":"XYZ246", "distance":60.7, "time":100}, {"plate":"ABC123", "distance":70.2, "time":200}, {"plate":"MNL357", "distance":40.3, "time":70} ] returnList = [] dst, time = defaultdict(int), defaultdict(int) for v in vehicles: dst[v["plate"]] += v["distance"] time[v["plate"]] += v["time"] dst = dict(dst) time = dict(time) for i in dst: returnList.append({"plate":i,"distance":dst[i], "time":time[i]}) print(returnList)
运行结果:
[ {'plate': 'ABC123', 'distance': 230.8, 'time': 560}, {'plate': 'XYZ246', 'distance': 100.7, 'time': 130}, {'plate': 'MNL357', 'distance': 40.3, 'time': 70} ]
优化方案
方案一:单字典存储汇总结果(高效简洁)
用单个defaultdict存储每个车牌对应的汇总数据,只需一次遍历即可完成统计,避免维护多个字典的冗余操作,最后通过列表推导式快速生成目标格式。
from collections import defaultdict vehicles = [ {"plate":"ABC123", "distance":80.3, "time":180}, {"plate":"ABC123", "distance":80.3, "time":180}, {"plate":"XYZ246", "distance":40.0, "time":30}, {"plate":"XYZ246", "distance":60.7, "time":100}, {"plate":"ABC123", "distance":70.2, "time":200}, {"plate":"MNL357", "distance":40.3, "time":70} ] # 初始化默认字典,每个键对应包含distance和time的汇总字典 summary = defaultdict(lambda: {"distance": 0.0, "time": 0}) for v in vehicles: plate = v["plate"] summary[plate]["distance"] += v["distance"] summary[plate]["time"] += v["time"] # 转换为目标列表格式 return_list = [{"plate": plate, **data} for plate, data in summary.items()] print(return_list)
优势:时间复杂度O(n),仅需一次遍历,代码简洁易维护,无额外开销。
方案二:使用itertools.groupby(适合有序列表)
如果原始列表已按plate排序,groupby可以高效分组;若未排序,需先排序(注意排序的O(n log n)开销)。
from itertools import groupby from operator import itemgetter vehicles = [ {"plate":"ABC123", "distance":80.3, "time":180}, {"plate":"ABC123", "distance":80.3, "time":180}, {"plate":"XYZ246", "distance":40.0, "time":30}, {"plate":"XYZ246", "distance":60.7, "time":100}, {"plate":"ABC123", "distance":70.2, "time":200}, {"plate":"MNL357", "distance":40.3, "time":70} ] # 先按plate排序(原列表无序时必须执行) vehicles_sorted = sorted(vehicles, key=itemgetter("plate")) return_list = [] # 按plate分组并汇总 for plate, group in groupby(vehicles_sorted, key=itemgetter("plate")): total_dist = 0.0 total_time = 0 for item in group: total_dist += item["distance"] total_time += item["time"] return_list.append({"plate": plate, "distance": total_dist, "time": total_time}) print(return_list)
优势:代码逻辑直观,适合已有序的数据集;劣势:无序数据集需排序,大数据量下性能不如方案一。
方案三:使用pandas(适合大数据/复杂统计)
如果处理的数据量较大,或后续需要更多统计操作(如平均值、最大值等),pandas的分组聚合功能会更高效且简洁。
import pandas as pd vehicles = [ {"plate":"ABC123", "distance":80.3, "time":180}, {"plate":"ABC123", "distance":80.3, "time":180}, {"plate":"XYZ246", "distance":40.0, "time":30}, {"plate":"XYZ246", "distance":60.7, "time":100}, {"plate":"ABC123", "distance":70.2, "time":200}, {"plate":"MNL357", "distance":40.3, "time":70} ] # 转换为DataFrame df = pd.DataFrame(vehicles) # 按plate分组求和,重置索引后转换为字典列表 summary_df = df.groupby("plate").sum().reset_index() return_list = summary_df.to_dict("records") print(return_list)
优势:pandas内部优化了聚合逻辑,大数据量下性能优于纯Python实现,支持多维度统计;劣势:需要额外安装pandas库,小数据量下没必要。
内容的提问来源于stack exchange,提问作者Juan Duque
相关产品推荐
相关产品推荐

