Python对字典列表按多键统计通过率等指标的高效实现方法
问题分析与优化实现
你原来的实现存在两个明显问题:
- 统计逻辑错误:
sum(["Passed" and "name" for d in input if 'Status' in d and name in d])中"Passed" and "name"的返回值固定为字符串name,求和时会被转为布尔值True(对应数值1),实际统计的是匹配name的所有条目总数,无法区分Passed和Failed的数量 - 效率低下:每统计一个name就要遍历一次全量数据集,时间复杂度为O(n*m)(n为总数据条数,m为不同name的数量),数据量大时性能损耗明显
你提到的直接循环对比字典字段值的思路确实更简单,基于这个思路可以实现一次遍历完成所有统计,效率和可读性都更高。
最优实现方案(一次遍历完成统计)
时间复杂度为O(n),逻辑简洁清晰:
# 如需兼容无额外库导入的场景,可把defaultdict替换为普通字典判断key是否存在 from collections import defaultdict # 初始化统计容器:key为name,value为[Passed数量, Failed数量] count_map = defaultdict(lambda: [0, 0]) total_passed = 0 total_failed = 0 for item in input: name = item["name"] status = item["Status"] if status == "Passed": count_map[name][0] += 1 total_passed += 1 elif status == "Failed": count_map[name][1] += 1 total_failed += 1 # 生成分组统计结果 output = [] for name, (passed, failed) in count_map.items(): total = passed + failed pass_rate = f"{int(passed / total * 100)}%" output.append({ "name": name, "Passed": str(passed), "Failed": str(failed), "Total": str(total), "%Pass": pass_rate }) # 追加全局合计行 total_all = total_passed + total_failed total_pass_rate = f"{int(total_passed / total_all * 100)}%" output.append({ "name": "Total", "Passed": str(total_passed), "Failed": str(total_failed), "Total": str(total_all), "%Pass": total_pass_rate })
无额外导入的普通字典实现
如果不想导入collections标准库,可替换统计容器的初始化逻辑,其余生成结果的代码完全一致:
count_map = {} total_passed = 0 total_failed = 0 for item in input: name = item["name"] status = item["Status"] # 首次遇到该name时初始化统计值 if name not in count_map: count_map[name] = [0, 0] if status == "Passed": count_map[name][0] += 1 total_passed += 1 elif status == "Failed": count_map[name][1] += 1 total_failed += 1
内容的提问来源于stack exchange,提问作者Hugo_Ludo_38
相关产品推荐
相关产品推荐

