如何将含层级标识键的Python字典转换为嵌套字典?
这是个挺常见的扁平化嵌套结构还原需求,我来给你拆解实现思路和具体代码,保证能搞定你的问题:
核心思路拆解
首先得把每个扁平化的键拆成层级节点,每个节点要分清是普通字典键还是列表索引。比如key2[0]得拆成键名key2和索引0,而key1就是普通的字典键。
接下来从根字典开始,逐层往下构建嵌套结构:
- 遇到普通字典键:如果父容器里没这个键,就创建空字典;然后移动到这个键对应的容器里继续处理下一层。
- 遇到列表索引:先确保父容器里的列表长度够装这个索引(不够的话就补空字典/占位符),然后定位到列表的对应索引位置,继续往下走。
- 最后处理最底层的赋值,把对应的值放到最终的位置上。
完整代码实现
下面是带详细注释的Python代码,直接就能用:
def flatten_to_nested(flat_dict): # 初始化最终的嵌套字典 nested = {} # 遍历每个扁平化的键值对 for flat_key, value in flat_dict.items(): # 按冒号拆分键的各个层级 parts = flat_key.split(':') # 从根字典开始导航 current = nested # 处理除最后一个层级外的所有节点 for part in parts[:-1]: # 判断当前节点是否是列表索引格式(比如key2[0]) if '[' in part and ']' in part: # 拆分出键名和索引 key, idx_str = part.split('[', 1) idx = int(idx_str.rstrip(']')) # 如果当前键不存在,创建空列表 if key not in current: current[key] = [] # 确保列表长度足够,不够就补空字典(避免索引越界) while len(current[key]) <= idx: current[key].append({}) # 移动到列表的对应索引位置 current = current[key][idx] else: # 普通字典键,不存在就创建空字典 if part not in current: current[part] = {} current = current[part] # 处理最后一个层级,赋值 last_part = parts[-1] if '[' in last_part and ']' in last_part: # 最后一个节点是列表索引 key, idx_str = last_part.split('[', 1) idx = int(idx_str.rstrip(']')) if key not in current: current[key] = [] # 确保列表长度足够,不够补占位符(这里用None,可根据需求调整) while len(current[key]) <= idx: current[key].append(None) current[key][idx] = value else: # 最后一个节点是普通字典键,直接赋值 current[last_part] = value return nested # 测试你的输入数据 flat_input = { "key1:key2[0]:key3[0]": "1234", "key1:key2[0]:key4[0]:key5": "4567", "key1:key2[1]:key3[0]": "789", "key1:key2[1]:key4[1]:key5": "12345" } # 生成嵌套结构并打印 result = flatten_to_nested(flat_input) import json print(json.dumps(result, indent=2))
运行结果
执行代码后会输出你想要的嵌套结构:
{ "key1": { "key2": [ { "key3": [ "1234" ], "key4": [ { "key5": "4567" } ] }, { "key3": [ "789" ], "key4": [ null, { "key5": "12345" } ] } ] } }
这里key4里的null是因为处理key1:key2[1]:key4[1]:key5时,索引0的位置没有对应值,代码自动补了None(JSON里显示为null)。如果不需要这个空值,可以调整代码逻辑,比如只在需要的时候创建列表元素,但这样可能会导致列表索引不连续,你可以根据自己的需求修改。
关键细节提醒
- 拆分键的时候用
split(':')分割层级,再通过判断[]来区分列表索引和普通键 - 处理列表时,用
while循环确保列表长度足够,避免索引越界错误 - 赋值阶段区分最后一个节点是列表还是普通键,分别处理逻辑
内容的提问来源于stack exchange,提问作者void
相关产品推荐
相关产品推荐

