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

如何更优雅地提取嵌套JSON中指定层级键的对应值

优化嵌套JSON键值提取代码

问题背景

我有如下嵌套字典结构(模拟JSON):

dict_obj = { "a1": { "b1" : 1 , "b2" : { "c1" : 24, "c2" : 25}, "b3" : { "c3" : 45, "c4" : 1, "c5" : 4} }, "a2" : 4}

指定三级键数组:

FIRSTS = ["a1"]
SECONDS = ["b1", "b3"]
THIRDS = ["c3"]

期望输出:[b1 : 1], [c3 : 45]

需求明确:

  • 仅提取值为非字典类型的键值对
  • 必须处理键不存在的情况

我已经实现了一段代码,但希望得到更简洁高效的写法,原代码如下:

message = ""
for first in FIRSTS:
  if first in json_object:
    if isinstance(json_object[first], dict):
      for second in SECONDS:
        if second in json_object[first]:
          if isinstance(json_object[first][second], dict):
            for third in THIRDS:
              if third in json_object[first][second]:
                message = message + f"[{third} : {json_object[first][second][third]}], "
              else:
                message = message + f"[{third} not found], "
          else:
            message = message + f"[{second} : {json_object[first][second]}], "
        else:
          message = message + f"[{second} not found], "
    else:
      message = message + f"[{first} : {json_object[first]}], "
  else:
    message = message + f"[{first} not found], "

print(message[:-2])

优化实现方案

方案1:拆分逻辑+列表收集结果

把键值提取的逻辑拆成辅助函数,降低代码嵌套深度,同时用列表替代字符串拼接提升效率:

def get_nested_value(data, key_chain):
    """逐层获取嵌套键的值,返回(值, 是否找到)"""
    current = data
    for key in key_chain:
        if not isinstance(current, dict) or key not in current:
            return (None, False)
        current = current[key]
    return (current, True)

def generate_result(data, first_keys, second_keys, third_keys):
    result_items = []
    for first in first_keys:
        val, found = get_nested_value(data, [first])
        if not found:
            result_items.append(f"[{first} not found]")
            continue
        if not isinstance(val, dict):
            result_items.append(f"[{first} : {val}]")
            continue
        
        # 遍历二级键
        for second in second_keys:
            val2, found2 = get_nested_value(val, [second])
            if not found2:
                result_items.append(f"[{second} not found]")
                continue
            if not isinstance(val2, dict):
                result_items.append(f"[{second} : {val2}]")
                continue
            
            # 遍历三级键
            for third in third_keys:
                val3, found3 = get_nested_value(val2, [third])
                if found3:
                    result_items.append(f"[{third} : {val3}]")
                else:
                    result_items.append(f"[{third} not found]")
    
    return ", ".join(result_items)

# 测试调用
dict_obj = { "a1": { "b1" : 1 , "b2" : { "c1" : 24, "c2" : 25}, "b3" : { "c3" : 45, "c4" : 1, "c5" : 4} }, "a2" : 4}
FIRSTS = ["a1"]
SECONDS = ["b1", "b3"]
THIRDS = ["c3"]

print(generate_result(dict_obj, FIRSTS, SECONDS, THIRDS))

方案2:用get方法简化判断(轻量版)

如果不想拆分函数,直接用字典的get()方法简化存在性判断,同时用列表收集结果:

dict_obj = { "a1": { "b1" : 1 , "b2" : { "c1" : 24, "c2" : 25}, "b3" : { "c3" : 45, "c4" : 1, "c5" : 4} }, "a2" : 4}
FIRSTS = ["a1"]
SECONDS = ["b1", "b3"]
THIRDS = ["c3"]

result_items = []
for first in FIRSTS:
    first_val = dict_obj.get(first)
    if first_val is None:
        result_items.append(f"[{first} not found]")
        continue
    if not isinstance(first_val, dict):
        result_items.append(f"[{first} : {first_val}]")
        continue
    
    for second in SECONDS:
        second_val = first_val.get(second)
        if second_val is None:
            result_items.append(f"[{second} not found]")
            continue
        if not isinstance(second_val, dict):
            result_items.append(f"[{second} : {second_val}]")
            continue
        
        for third in THIRDS:
            third_val = second_val.get(third)
            if third_val is not None:
                result_items.append(f"[{third} : {third_val}]")
            else:
                result_items.append(f"[{third} not found]")

print(", ".join(result_items))

优化细节说明

  1. 替换字符串拼接:原代码用message += ...反复拼接字符串,Python中字符串是不可变对象,每次拼接都会生成新对象,数据量大时效率很低。改用列表收集所有结果项,最后用", ".join()一次性拼接,性能更优。
  2. 降低嵌套深度:原代码有4层嵌套的if-else,可读性和可维护性差。优化后通过辅助函数或扁平化的判断逻辑,让代码结构更清晰。
  3. 逻辑复用:方案1中的get_nested_value函数可以复用在各层级的键值获取中,减少重复代码,后续要扩展层级也更方便。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 18:07:14