如何通过递归精准移除JSON中的指定路径嵌套键?
按路径精准删除嵌套JSON中的指定键
修改后的实现代码
def remove_keys_by_path(d, paths_to_remove): # 预处理删除规则:统一转换为路径元组,比如'name'转成('name',) processed_paths = set() for path in paths_to_remove: if isinstance(path, str): processed_paths.add((path,)) else: processed_paths.add(tuple(path)) def _recursive_remove(current_obj, current_path): # 基础类型直接返回 if not isinstance(current_obj, (dict, list)): return current_obj # 处理列表:遍历每个元素,路径不变(列表元素无键) if isinstance(current_obj, list): return [_recursive_remove(item, current_path) for item in current_obj] # 处理字典:遍历键值对,判断当前键的完整路径是否在删除列表中 cleaned_dict = {} for key, value in current_obj.items(): full_path = current_path + (key,) if full_path not in processed_paths: # 保留键,递归处理值,更新当前路径为full_path cleaned_dict[key] = _recursive_remove(value, full_path) return cleaned_dict return _recursive_remove(d, ())
测试示例
使用你提供的原始JSON:
original_data = { "results": [{ "name": "john doe", "age": "100", "owned_cars": [{ "make": "ford", "color": "white" }, { "make": "bmw", "color": "red" }], "wished_cars": [{ "make": "honda" }, { "make": "toyota", "style": "sleek" }, { "style": "fat" }] }] } # 指定要删除的路径:owned_cars下的make,以及根路径的name paths = (('owned_cars', 'make'), 'name') result = remove_keys_by_path(original_data, paths)
执行后得到的结果:
{ "results": [{ "age": "100", "owned_cars": [{ "color": "white" }, { "color": "red" }], "wished_cars": [{ "make": "honda" }, { "make": "toyota", "style": "sleek" }, { "style": "fat" }] }] }
可以看到,wished_cars中的make被保留,只有owned_cars下的make和根路径的name被删除,符合需求。
递归问题的核心思路
- 状态跟踪:递归过程中必须传递当前的路径信息,这是实现精准匹配的关键。每进入一个字典的键,就把该键追加到当前路径中,这样就能明确当前键在整个嵌套结构中的位置。
- 规则统一化:将不同形式的删除规则(字符串单键、元组路径)统一转换为元组格式,存入集合中,这样可以用O(1)的时间复杂度判断当前路径是否需要删除,提升效率。
- 分类型处理:针对字典、列表、基础类型分别处理:
- 基础类型直接返回,终止递归;
- 列表遍历每个元素递归,路径不变(因为列表元素没有键,不影响路径);
- 字典则逐个判断键的完整路径,决定是否保留,同时递归处理值时更新路径。
- 嵌套递归逻辑:通过内部嵌套函数封装递归逻辑,对外暴露简洁的接口,同时避免外部传递不必要的参数(比如
current_path)。
内容的提问来源于stack exchange,提问作者cauthon
相关产品推荐
相关产品推荐

