如何更优雅地提取嵌套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))
优化细节说明
- 替换字符串拼接:原代码用
message += ...反复拼接字符串,Python中字符串是不可变对象,每次拼接都会生成新对象,数据量大时效率很低。改用列表收集所有结果项,最后用", ".join()一次性拼接,性能更优。 - 降低嵌套深度:原代码有4层嵌套的
if-else,可读性和可维护性差。优化后通过辅助函数或扁平化的判断逻辑,让代码结构更清晰。 - 逻辑复用:方案1中的
get_nested_value函数可以复用在各层级的键值获取中,减少重复代码,后续要扩展层级也更方便。
内容的提问来源于stack exchange,提问作者Luken Irazoqui
相关产品推荐
相关产品推荐

