Python递归转换路径字典为树形结构结果异常,求排查错误
字典转树形结构的递归函数错误分析
问题场景
输入表示树路径的Python字典:
{ "example": { "dir2": { "file4": {}, "file5": {} }, "dir1": { "file1": {}, "file2": {}, "dir5": {}, "dir4": { "file3": {} } } } }
期望转换为如下树形结构:
{ "name": "example", "children": [ { "name": "dir2", "children": [ { "name": "file4" }, { "name": "file5" } ] }, { "name": "dir1", "children": [ { "name": "file1" }, { "name": "file2" }, { "name": "dir5", "children": [] }, { "name": "dir4", "children": [ { "name": "file3" } ] } ] } ] }
编写的递归函数如下:
import json def convert_dict(dic): name = list(dic.keys())[0] d = {'name': name} if dic[name]: d['children']=[convert_dict(dic[name][x]) for x in list(dic[name].keys())] return d tree_dict = { "example": { "dir2": { "file4": {}, "file5": {} }, "dir1": { "file1": {}, "file2": {}, "dir5": {}, "dir4": { "file3": {} } } } } print(json.dumps(convert_dict(tree_dict), indent=2))
运行后仅得到部分节点:
{ "name": "example", "children": [ { "name": "file4" }, { "name": "file1" } ] }
错误原因
- 节点与子项的对应关系逻辑错误:
函数每次提取传入字典的第一个键作为当前节点名称,但遍历子节点时,传入的是子键对应的完整字典(比如dir2对应的{"file4": {}, "file5": {}})。此时函数会错误地将这个字典的第一个键(file4)当作当前节点,直接跳过了dir2这个中间节点。 - 空字典节点未处理:
对于原字典中值为空字典的节点(比如dir5),原函数未添加"children": []字段,不符合期望格式。
修正后的代码
方案1:拆分函数,明确节点构建逻辑
import json def build_node(name, children_dict): node = {"name": name} # 递归构建子节点,空字典则生成空children列表 node["children"] = [build_node(child_name, child_content) for child_name, child_content in children_dict.items()] if children_dict else [] return node def convert_dict(dic): # 提取根节点名称和对应的子字典 root_name = list(dic.keys())[0] return build_node(root_name, dic[root_name]) tree_dict = { "example": { "dir2": { "file4": {}, "file5": {} }, "dir1": { "file1": {}, "file2": {}, "dir5": {}, "dir4": { "file3": {} } } } } print(json.dumps(convert_dict(tree_dict), indent=2))
方案2:直接修正原递归逻辑
import json def convert_dict(dic): name = list(dic.keys())[0] node = {"name": name} children_dict = dic[name] if children_dict: children = [] for child_name, child_content in children_dict.items(): child_node = {"name": child_name} # 递归处理子内容,需包装为单键字典适配函数输入 if child_content: child_node["children"] = convert_dict({child_name: child_content})["children"] else: child_node["children"] = [] children.append(child_node) node["children"] = children else: node["children"] = [] return node tree_dict = { "example": { "dir2": { "file4": {}, "file5": {} }, "dir1": { "file1": {}, "file2": {}, "dir5": {}, "dir4": { "file3": {} } } } } print(json.dumps(convert_dict(tree_dict), indent=2))
修正逻辑说明
- 明确每个节点的
name对应原字典的键,子节点由该键对应的字典生成,避免了原函数跳过中间节点的问题。 - 主动为空字典节点添加
"children": []字段,完全匹配期望输出格式。 - 拆分
build_node函数的方案更直观,将节点名称与子字典的处理逻辑分离,降低递归复杂度。
内容的提问来源于stack exchange,提问作者voron.run
相关产品推荐
相关产品推荐

