Python中如何用多层键列表作为字典键操作嵌套字典?
嵌套字典多层键访问实现方案
原生Python字典仅支持单层键的直接索引,要实现传入多层键组成的列表/元组,就能直接穿透到嵌套层级取值、赋值的效果,只需要自定义一个继承自dict的子类,重写__getitem__(取值逻辑)和__setitem__(赋值逻辑)两个内置魔术方法即可。
核心实现逻辑
- 兼容原生字典的单层字符串键用法,避免将字符串误判为多键路径拆分成逐字符迭代
- 接收到多键列表/元组时,从字典最外层开始,顺着键的顺序逐层下钻到目标位置
- 取值过程中遇到不存在的键时,抛出和原生字典一致的
KeyError,保持行为兼容 - 赋值过程中自动补建路径上缺失的中间嵌套字典,不需要手动预建空层级
完整代码示例
class NestedDict(dict): def __getitem__(self, key): # 兼容点分字符串作为多键路径的场景 if isinstance(key, str) and "." in key: key = key.split(".") # 普通单层字符串键直接走原生字典逻辑 if isinstance(key, str): return super().__getitem__(key) # 顺着嵌套路径逐层取值 current = self for k in key: current = super(NestedDict, current).__getitem__(k) return current def __setitem__(self, key, value): # 兼容点分字符串作为多键路径的场景 if isinstance(key, str) and "." in key: key = key.split(".") # 普通单层字符串键直接走原生字典逻辑 if isinstance(key, str): super().__setitem__(key, value) return # 拆解路径,定位到最内层的父字典 current = self key_path = list(key) # 遍历非最后一层的路径,自动补建缺失的嵌套字典 for k in key_path[:-1]: if k not in current: current[k] = {} current = current[k] # 对最终目标位置赋值 current[key_path[-1]] = value
使用方式
把JSON解析生成的普通字典包装为上述自定义类的实例,就可以直接使用多键列表做索引:
# 从JSON解析得到的原始字典 original_env_dict = { "environmental": { "temprature": { "test": "temprature", "unit": "c", "now": 12.65, "now_timestamp": "10-06-2019 08:02:18" } } } # 包装为支持多键索引的嵌套字典对象 var_dict_x = NestedDict(original_env_dict) # 定义多键路径 var_lst_key = ["environmental", "temprature", "now"]
- 直接通过多键列表取值:
print(var_dict_x[var_lst_key]) # 输出结果:12.65
- 直接通过多键列表赋值:
var_dict_x[var_lst_key] = "x" print(var_dict_x[var_lst_key]) # 输出结果:x
- 兼容原生字典的原有多层点索引写法,两者可以混用:
print(var_dict_x["environmental"]["temprature"]["unit"]) # 输出结果:c # 也支持直接用点分字符串当键,比如 print(var_dict_x["environmental.temprature.test"]) # 输出结果:temprature
注意事项
- 子类完全继承原生字典的所有特性,像
get()方法、键存在判断、字典迭代、键值删除等操作都不需要额外改造,和原生字典行为完全一致 - 赋值时自动补建路径的特性,意味着就算目标键之前的所有中间层级都不存在,也可以直接赋值,比如
var_dict_x["new", "path", "key"] = 123会自动创建从顶层到目标位置的全层级嵌套结构,不会抛键错误
内容的提问来源于stack exchange,提问作者Werner Venter
相关产品推荐
相关产品推荐

