在计算机科学中,树形结构是最优雅的数据组织形式之一。虽然我们很少显式地创建树数据结构,但实际上每天处理的JSON数据都是天然的树形结构。就像俄罗斯套娃一样,层层嵌套的JSON数据完美展现了树的递归本质。本文将带您用递归的眼光重新认识JSON,解锁数据处理的新视角。
一、JSON的树形本质
任何JSON对象都可以看作一个多叉树:
- 根节点:整个JSON对象
- 内部节点:字典(dict)或列表(list)
- 叶子节点:基本数据类型(字符串/数字/布尔值)
二、示例
1. 深度优先遍历
def traverse_json(node, depth=0):
if isinstance(node, dict):
for key, value in node.items():
print(" " * depth + f"Key: {key}")
traverse_json(value, depth+1)
elif isinstance(node, list):
for item in node:
traverse_json(item, depth+1)
else:
print(" " * depth + f"Value: {node}")
family_tree = {
"name": "祖父",
"children": [
{
"name": "父亲",
"children": [
{"name": "我", "pet": "🐱"},
{"name": "妹妹"}
]
},
{
"name": "叔叔",
"children": []
}
]
}
traverse_json(family_tree)
# 输出
Key: name
Value: 祖父
Key: children
Key: name
Value: 父亲
Key: children
Key: name
Value: 我
Key: pet
Value: 🐱
Key: name
Value: 妹妹
Key: name
Value: 叔叔
Key: children
2. 路径收集器
import json
from collections import defaultdict
def collect_path_mapping(obj, current_tar_path, path_mapping):
if isinstance(obj, dict):
current_tar_path = obj.get("tar_path", current_tar_path)
for key, value in obj.items():
if key == "file_path":
path_mapping[current_tar_path].append(value)
else:
collect_path_mapping(value, current_tar_path, path_mapping)
elif isinstance(obj, list):
for item in obj:
collect_path_mapping(item, current_tar_path, path_mapping)
# 示例 JSON 数据
obj = {
"tar_path": "path/to/tar",
"sub_dict": {
"text": "This is a text",
"sub_list": [
{
"description": "This is a sub_list_item",
"file_path": "path/to/sub_list_audio"
},
{
"description": "This is another sub_list_item",
"file_path": "path/to/sub_list_audio2"
}
]
}
}
path_mapping = defaultdict(list)
collect_path_mapping(obj, None, path_mapping)
print(json.dumps(dict(path_mapping), indent=4))
# 输出
{
"path/to/tar": [
"path/to/sub_list_audio",
"path/to/sub_list_audio2"
]
}
三、何时选择递归
✅ 适用场景:
- 未知嵌套深度的数据
- 需要完整遍历的场景
- 树状结构操作(如DFS)
⛔ 注意事项:
- 嵌套过深可能导致栈溢出(Python默认递归深度约1000层)
- 循环引用会导致无限递归
- 大数据量时考虑性能问题
结语
递归处理JSON的过程,本质上是与数据的树形结构对话。当我们用递归的眼光看待嵌套数据时,复杂的层级关系会自然展开。这种思维方式不仅能提升代码的优雅度,更能帮助我们洞察数据的内在逻辑。下次面对嵌套JSON时,不妨想象自己正在遍历一棵无形的数据之树,让递归成为您手中的探索利刃。