python - 在 Python 中转换嵌套的字典列表
问题描述
我想将嵌套的字典列表转换为子结构。并找到一种强大的方法来做到这一点。结构:
nested_list = [
{
"id" : "fruit",
"name" : "apple"
},
{
"name": "fruit"
},
{
"id" : "fruit",
"name" : "grape"
},
{
"id" : "fruit",
"name" : "pineapple"
},
{
"name": "vehicle"
},
{
"id" : "vehicle",
"name": "car"
},
{
"id" : "car",
"name": "sedan"
},
]
进入:
{
"vehicle": {
"car": {
"sedan" : {}
}
},
"fruit" : {
"apple": {},
"grape": {},
"pineapple": {}
}
}
请注意,在这种情况下,它可以下降两级。但它也可以深入三层。例如一个额外的条目:
{
"id" : "sedan",
"name": "mini sedan"
}
到目前为止,我的方法是:
for category in nested_list:
if 'id' not in category:
d[category['name']] = {}
for category in nested_list:
if 'id' in category and category['id'] in d:
d[category['id']][category['name']] = {}
elif 'id' in category and category['id'] not in d:
for k, v in d.items():
if category['id'] in v:
d[k][category['id']] = {category['name']: {}}
# If there are not top level key then do nothing
else:
pass
它适用于这种情况。问题是它不够健壮。我正在考虑递归,但无法破解它。有人可以帮忙吗?谢谢
解决方案
解决方案
您可以使用collections.defaultdict
和dict.setdefault
:
from collections import defaultdict
nested_list = [
{
"id": "fruit",
"name": "apple"
},
{
"name": "fruit"
},
{
"id": "fruit",
"name": "grape"
},
{
"id": "fruit",
"name": "pineapple"
},
{
"name": "vehicle"
},
{
"id": "vehicle",
"name": "car"
},
{
"id": "car",
"name": "sedan"
},
{
"id": "sedan",
"name": "mini sedan"
},
]
working_dict = defaultdict(dict)
result_dict = {}
for item in nested_list:
name = item['name']
if 'id' in item:
id_ = item['id']
working_dict[id_].setdefault(name, working_dict[name])
else:
result_dict[name] = working_dict[name]
print(working_dict)
print(result_dict)
输出:
defaultdict(<class 'dict'>, {'fruit': {'apple': {}, 'grape': {}, 'pineapple': {}}, 'apple': {}, 'grape': {}, 'pineapple': {}, 'vehicle': {'car': {'sedan': {'mini sedan': {}}}}, 'car': {'sedan': {'mini sedan': {}}}, 'sedan': {'mini sedan': {}}, 'mini sedan': {}})
{'fruit': {'apple': {}, 'grape': {}, 'pineapple': {}}, 'vehicle': {'car': {'sedan': {'mini sedan': {}}}}}
解释
- 这个想法:
dict
是可变的。 working_dict
是所有"id"
s 的参考表。- 如果没有这样的id,注册
{}
它。 - 并将没有
id
字段的元素作为根元素注册到result_dict
.
附加
不想用collections.defaultdict
就只能用dict.setdefault
。但它更冗长。
working_dict = {}
result_dict = {}
for item in nested_list:
name = item['name']
if 'id' in item:
id_ = item['id']
working_dict.setdefault(id_, {}).setdefault(name, working_dict.setdefault(name, {}))
else:
result_dict[name] = working_dict.setdefault(name, {})
print(result_dict)
推荐阅读
- c# - 如何避免在不需要时解决服务?
- google-cloud-platform - 如何使用 cli 或控制台在 GCP 中列出组 ID
- arrays - 如何在 switch 语句中使用数组?
- flutter - 如何在vs代码中连接LD播放器?
- facebook - 错误不支持获取请求。ID 为 xxx 的对象不存在
- autodesk-forge - 在 Forge Viewer 中使用 BIM360 模型坐标变换位置?
- python - 如何列出可以在 seaborn 中作为关键字参数发送的所有值
- asp.net - 在 asp.net 中下载 SQL 备份文件
- python - 覆盖事件会阻止信号/插槽触发
- javascript - MongoDB Atlas 多范围搜索