如何使用字符串索引访问含嵌套列表的Python字典值?
问题:通过字符串索引访问嵌套字典/列表的值
我有一个由JSON转换而来的大型嵌套字典,结构如下:
dictionary = { "Thing1": { "Thing1.1": { "Thing1.1.1": "Text", "Thing1.1.2": "Text", "Thing1.1.3": "Text"}, "Thing1.2": [{ "Thing1.2.1.1": "Text", "Thing1.2.1.2": "Text", "Thing1.2.1.3": "Text"}, { "Thing1.2.2.1": "Text", "Thing1.2.2.2": "Text", "Thing1.2.2.3": "Text we're interested in"} ], "Thing1.3": { "Thing1.3.1": "Text", "Thing1.3.2": "Text", "Thing1.3.3": "Text"} }, "Thing2": { "Thing2.1": { "Thing2.1.1": "Text", "Thing2.1.2": "Text", "Thing2.1.3": "Text"}, "Thing2.2": { "Thing2.2.1": "Text", "Thing2.2.2": "Text", "Thing2.2.3": "Text"}, "Thing2.3": { "Thing2.3.1": "Text", "Thing2.3.2": "Text", "Thing2.3.3": "Text"} }, "Thing3": { "Thing3.1": { "Thing3.1.1": "Text", "Thing3.1.2": "Text", "Thing3.1.3": "Text"}, "Thing3.2": { "Thing3.2.1": "Text", "Thing3.2.2": "Text", "Thing3.2.3": "Text"}, "Thing3.3": { "Thing3.3.1": "Text", "Thing3.3.2": "Text", "Thing3.3.3": "Text"} } }
经过自动化处理后,得到一个字符串形式的目标值索引:
key = '["Thing1"]["Thing1.2"][1]["Thing1.2.2.3"]'
希望通过该字符串索引直接访问对应的值,就像执行:
value = dictionary["Thing1"]["Thing1.2"][1]["Thing1.2.2.3"]
曾尝试用exec结合f-string实现,但存在全局与局部变量作用域等问题,因此寻求更优解决方案。
补充说明:该字典为任意深度结构,其中可能嵌套有列表(如示例中的Thing1.2)。
解决方案
方法1:手动解析索引字符串,逐层访问
手动处理索引字符串,提取路径片段后,依次遍历嵌套结构,区分字典键和列表索引,安全访问目标值。
def get_nested_value(data, key_str): # 提取路径片段:去掉首尾[],按']['分割 path_parts = key_str.strip('[]').split('][') current_obj = data for part in path_parts: if part.startswith('"') and part.endswith('"'): # 处理字典键:去除引号 key = part.strip('"') current_obj = current_obj[key] else: # 处理列表索引:转为整数 idx = int(part) current_obj = current_obj[idx] return current_obj # 测试调用 value = get_nested_value(dictionary, key) print(value) # 输出:Text we're interested in
优点:无需依赖额外模块,完全可控,无代码注入风险,适配任意深度的嵌套结构。
方法2:使用ast模块安全解析表达式
利用Python内置的ast模块解析索引字符串,构造安全的表达式执行,避免exec的作用域和安全问题。
import ast def get_nested_value_ast(data, key_str): # 构造完整的访问表达式 expr = f"data{key_str}" # 解析抽象语法树,验证表达式安全性 tree = ast.parse(expr, mode='eval') # 执行表达式,传入data作为局部变量 return eval(compile(tree, filename='', mode='eval'), {'data': data}) # 测试调用 value = get_nested_value_ast(dictionary, key) print(value) # 输出:Text we're interested in
优点:代码简洁,比exec更安全(ast会先做语法校验,避免恶意代码注入),同时解决了作用域问题。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

