Python 按指定键对字典列表去重:保留重复项最后一项的实现优化
字典列表按指定键去重的优化实现
现有实现的问题
你当前写的代码已经覆盖了“同指定键值保留最后出现条目、无指定键条目全保留”的核心逻辑,但存在明显的顺序错位问题:
- 代码会把所有不含指定键的字典提前放到结果集最前端,再把所有带指定键的去重条目拼在最后,完全打乱了原列表的元素相对顺序,甚至跑通不了你自己给出的测试示例。
- 针对你提供的示例输入,当前代码返回的结果会是
[{'c':'cheat','d':'dog'}, {'a':'apple','c':'cat'}, {'a':'amazon','c':'cheat'}],和你标注的预期顺序不符。
优化方案
按照“保留原列表元素相对位置、仅替换重复键值的条目为最后出现版本、不移动无键条目位置”的隐含需求,可以用更简洁的实现,完全适配Python3.7+的有序字典特性:
def dedupe(dict_list, dedupe_key): seen = {} res = [] for item in dict_list: # 无指定键的条目直接按原位置保留 if dedupe_key not in item: res.append(item) continue key_val = item[dedupe_key] # 首次遇到的键值,在对应位置占位 if key_val not in seen: res.append(None) seen[key_val] = len(res) - 1 # 每次遇到同键值条目,直接替换占位为最新的字典内容,保证留最后一次出现的版本 res[seen[key_val]] = item return res
测试验证
用你提供的示例输入运行上述代码,返回结果和预期完全一致:
list_dicts = [ {'a':'apple','b':'ball'}, {'a':'apple','c':'cat'}, {'c':'cheat','d':'dog'}, {'a':'amazon','c':'cheat'} ] print(dedupe(list_dicts, dedupe_key='a')) # 输出: [{'a':'apple','c':'cat'}, {'c':'cheat','d':'dog'}, {'a':'amazon','c':'cheat'}]
极致简化的场景化写法
如果业务上对原列表的元素顺序不敏感,只需要“同键值留最后出现的条目、无键条目全保留”,可以把代码压缩成更短的字典推导式版本,本质是你原有循环逻辑的语法糖:
def dedupe(dict_list, dedupe_key): no_key_items = [item for item in dict_list if dedupe_key not in item] key_items = {item[dedupe_key]: item for item in dict_list if dedupe_key in item}.values() return no_key_items + list(key_items)
注意:这个版本会把所有无键条目放到结果集最前面,和你原有代码的逻辑完全一致,仅适合对元素位置无要求的场景。
内容的提问来源于stack exchange,提问作者Deepak Gaur
相关产品推荐
相关产品推荐

