Python 3.5.2字典列表按id去重:保留非空值最多的字典
解决按id去重并保留非空值最多字典的方案
这问题我之前也碰到过,不用pandas完全可以搞定,咱们一步步来实现:
核心思路
我们可以用一个临时字典来按id分组,每个id对应当前找到的非空值数量最多的字典。遍历原列表时,逐个对比每个字典的非空值数量,更新临时字典里的最优项即可。
先修正非空值统计逻辑
你之前用len(set([v for v in d.values() if v]))来统计非空值数量有个小问题:set会自动去重,比如如果字典里有两个相同的非空值,会被算成1个,但实际非空值是2个。如果你的需求是统计非空值的个数(而不是不同非空值的数量),应该用下面的方式:
# 统计字典中非None的键值对数量(如果空字符串也算"空",可以加上 `and v != ""`) non_empty_count = sum(1 for v in d.values() if v is not None)
完整实现代码
d1 = {"id":"a", "foo":"bar", "baz":"bat"} d2 = {"id":"b", "foo":"bar", "baz":None} d3 = {"id":"a", "foo":"bar", "baz":None} d4 = {"id":"b", "foo":"bar", "baz":"bat"} l = [d1, d2, d3, d4] # 临时字典:key是id,value是(非空值数量, 对应字典) id_best_map = {} for d in l: current_id = d["id"] # 计算当前字典的非空值数量 count = sum(1 for v in d.values() if v is not None) # 检查当前id是否已在临时字典中 if current_id not in id_best_map: id_best_map[current_id] = (count, d) else: existing_count, existing_dict = id_best_map[current_id] # 如果当前字典的非空值更多,就替换掉 if count > existing_count: id_best_map[current_id] = (count, d) # 提取最终结果:从临时字典中取出所有最优字典 result = [dict_item for _, dict_item in id_best_map.values()] print(result)
运行后会输出:
[{'id': 'a', 'foo': 'bar', 'baz': 'bat'}, {'id': 'b', 'foo': 'bar', 'baz': 'bat'}]
为什么这个方案可行?
- 完全基于Python标准库,不需要额外安装依赖,符合你的项目限制
- 时间复杂度是O(n*m)(n是列表长度,m是每个字典的键值对数量),对于普通规模的数据足够高效
- 逻辑清晰,容易理解和维护,也方便根据需求调整(比如修改非空值的定义)
内容的提问来源于stack exchange,提问作者foobarbaz
相关产品推荐
相关产品推荐

