Python中字典Upsert操作的优化方案咨询
解决字典更新时列表去重(兼容不可哈希元素)的方案
核心思路
针对列表元素不可哈希的场景,放弃集合去重的方式,改用遍历对比元素内容的逻辑判断重复,同时可保留列表原有顺序(适配前端展示需求)。
具体实现方案
1. 通用列表去重工具函数
先实现一个支持不可哈希元素的去重函数,可自定义重复判断规则:
def deduplicate_list(lst, key=None): """ 列表去重,兼容不可哈希元素 :param lst: 待去重列表 :param key: 可选,自定义对比键(比如针对字典元素,指定用某个字段判断重复) :return: 去重后的新列表,保留原顺序 """ seen = [] for item in lst: compare_item = key(item) if key else item if compare_item not in seen: seen.append(compare_item) yield item return list(seen)
2. 改进后的字典更新函数
将去重逻辑整合到字典更新流程中,指定需要去重的列表字段:
def upsert_dictionary(target, update, list_dedup_keys=None): """ 更新字典,指定列表字段自动去重 :param target: 后端原始字典 :param update: 前端传来的更新字典 :param list_dedup_keys: 需要去重的列表字段名列表,如["tags", "items"] :return: 更新后的字典 """ list_dedup_keys = list_dedup_keys or [] for k, v in update.items(): if k in target: # 处理需要去重的列表字段 if isinstance(target[k], list) and isinstance(v, list) and k in list_dedup_keys: combined = target[k] + v target[k] = list(deduplicate_list(combined)) # 递归处理嵌套字典 elif isinstance(target[k], dict) and isinstance(v, dict): upsert_dictionary(target[k], v, list_dedup_keys) # 普通字段直接覆盖 else: target[k] = v else: # 新增字段直接赋值 target[k] = v return target
3. 嵌套场景与自定义规则示例
如果后端数据是嵌套结构,且列表元素为复杂对象:
# 后端原始数据 backend_data = { "user": { "name": "Alice", "hobbies": [{"id": 1, "name": "reading"}, {"id": 2, "name": "hiking"}] } } # 前端更新内容 frontend_update = { "user": { "hobbies": [{"id": 2, "name": "hiking"}, {"id": 3, "name": "painting"}] } } # 调用更新,指定按hobbies字段的id去重 upsert_dictionary(backend_data, frontend_update, list_dedup_keys=["hobbies"]) # 最终hobbies结果:[{"id":1, "name":"reading"}, {"id":2, "name":"hiking"}, {"id":3, "name":"painting"}]
方案优势
- 完全兼容不可哈希的列表元素(如字典、嵌套列表)
- 保留列表元素原有顺序,适配前端展示逻辑
- 支持嵌套字典的递归更新
- 可自定义重复判断规则,灵活性强
内容的提问来源于stack exchange,提问作者Jeroen Vermunt
相关产品推荐
相关产品推荐

