
本文介绍一种通用、可复用的递归方法,将具有深层嵌套结构(如地区层级:国家→州→城市→街道→门牌)的字典列表展平为扁平化的对象列表,保留关键字段(person/city/address/facebooklink),并确保地址路径准确反映层级关系。
在处理地理层级、组织架构或树形配置等数据时,常遇到类似 {"united states": [{"person": "...", "ohio": [...]}, ...]} 这类嵌套结构——其中每个节点既包含自身属性(如 person, address),又以同名键(如 "ohio")嵌套下级列表。目标是提取所有层级中的有效实体对象,忽略仅作容器用途的键(如 "united states"、"ohio" 等动态键名),仅保留含业务字段的字典。
以下是一个健壮、清晰的递归展平函数:
def flatten_objects(data):
"""
递归展平嵌套字典列表,提取所有含 person/city/address/facebooklink 的叶子节点。
Args:
data: list 或 dict 类型的嵌套结构(支持混合嵌套)
Returns:
list: 扁平化后的字典列表,每个字典包含原始业务字段
"""
result = []
# 处理输入为列表的情况(最外层及各级子列表)
if isinstance(data, list):
for item in data:
result.extend(flatten_objects(item))
return result
# 处理输入为字典的情况
if isinstance(data, dict):
# 提取当前层级的业务字段(非列表值)
current_fields = {}
nested_lists = {}
for key, value in data.items():
if isinstance(value, list):
# 将值为列表的项暂存,后续递归处理
nested_lists[key] = value
else:
# 保留基础字段(person, city, address, facebooklink 等)
current_fields[key] = value
# 若当前字典包含业务字段,则自身作为一条记录加入结果
if current_fields:
result.append(current_fields)
# 递归处理所有嵌套列表(如 "united states": [...], "ohio": [...])
for nested_key, nested_value in nested_lists.items():
if isinstance(nested_value, list):
result.extend(flatten_objects(nested_value))
return result✅ 使用示例:
# 示例数据(与问题中结构一致)
nested_data = [
{
"person": "abc",
"city": "united states",
"facebooklink": "link",
"address": "united states",
"united states": [
{
"person": "cdf",
"city": "ohio",
"facebooklink": "link",
"address": "united states/ohio",
"ohio": [
{
"person": "efg",
"city": "clevland",
"facebooklink": "link",
"address": "united states/ohio/clevland",
"clevland": [
{
"person": "jkl",
"city": "Street A",
"facebooklink": "link",
"address": "united states/ohio/clevland/Street A",
"Street A": [
{
"person": "jkl",
"city": "House 1",
"facebooklink": "link",
"address": "united states/ohio/clevland/Street A/House 1"
}
]
}
]
},
{
"person": "ghi",
"city": "columbus",
"facebooklink": "link",
"address": "united states/ohio/columbus"
}
]
},
{
"person": "abc",
"city": "washington",
"facebooklink": "link",
"address": "united states/washington"
}
]
}
]
# 展平并打印
flattened = flatten_objects(nested_data)
for obj in flattened:
print(obj)? 关键设计说明:
立即学习“Python免费学习笔记(深入)”;
- ✅ 智能识别容器键:不依赖硬编码键名(如 "united states"),而是通过 isinstance(value, list) 自动识别嵌套列表字段,适应任意层级命名;
- ✅ 保留完整路径:address 字段已预置完整层级路径(如 "united states/ohio/clevland/Street A/House 1"),无需额外拼接;
- ✅ 安全递归:避免无限循环,严格区分 list / dict / 基础类型,对空值或非标准结构具备鲁棒性;
- ⚠️ 注意事项:若原始数据中存在同名但语义不同的字段(如某层 city 是字符串,另一层是对象),需按实际业务逻辑增强字段校验逻辑;
- ? 扩展建议:如需控制输出顺序(如按 address 深度升序),可在返回前添加 sorted(flattened, key=lambda x: x.get("address", "").count("/"))。
该方案比依赖第三方库(如 flatten_json)更轻量、更可控,且完全适配此类“业务字段 + 动态容器键”混合嵌套场景,是生产环境中推荐的标准化展平实践。










