You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过递归精准移除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被删除,符合需求。

递归问题的核心思路

  1. 状态跟踪:递归过程中必须传递当前的路径信息,这是实现精准匹配的关键。每进入一个字典的键,就把该键追加到当前路径中,这样就能明确当前键在整个嵌套结构中的位置。
  2. 规则统一化:将不同形式的删除规则(字符串单键、元组路径)统一转换为元组格式,存入集合中,这样可以用O(1)的时间复杂度判断当前路径是否需要删除,提升效率。
  3. 分类型处理:针对字典、列表、基础类型分别处理:
    • 基础类型直接返回,终止递归;
    • 列表遍历每个元素递归,路径不变(因为列表元素没有键,不影响路径);
    • 字典则逐个判断键的完整路径,决定是否保留,同时递归处理值时更新路径。
  4. 嵌套递归逻辑:通过内部嵌套函数封装递归逻辑,对外暴露简洁的接口,同时避免外部传递不必要的参数(比如current_path)。

内容的提问来源于stack exchange,提问作者cauthon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 08:36:22