[英]python - Convert list of dicts to hierarchy/multiple nested dicts - issue with orders
目前,我有以下输入:
query = [{'id': 1, 'desc': 'desc_father', 'parent_id': None}
,{'id': 2, 'desc': 'desc_child_1', 'parent_id': 10}
,{'id': 3, 'desc': 'desc_child_2', 'parent_id': 2}
,{'id': 4, 'desc': 'desc_child_5', 'parent_id': 5}
,{'id': 5, 'desc': 'desc_child_6', 'parent_id': 6}
,{'id': 6, 'desc': 'desc_child_1', 'parent_id': 1}]
这是我的递归函数:
def recursive(parent_list, child_dict, parent_id):
for l in parent_list:
if parent_id in l.values():
if 'children' not in l:
l['children'] = []
l['children'].append(child_dict)
break
else:
for i in l:
if isinstance(l[i], list):
recursive(d[i], child_dict, parent_id)
return parent_list
这是我的主要代码:
results = []
for q in query:
dict_item = {}
dict_item['id'] = q['id']
dict_item['desc'] = q['desc']
if q['parent_id'] is None:
results.append(dict_item)
else:
results= recursive(results, dict_item, q['parent_id'])
return results
因此,使用上述给定的数据和代码,结果如下:
[{
'desc' : 'desc_father',
'id' : 1,
'children' : [{
'desc' : 'desc_child_1',
'id' : 2,
'children' : [{
'desc' : 'desc_child_2',
'id' : 3
}
]
}, {
'desc' : 'desc_child_1',
'id' : 6
}
]
}
]
结果是,您会看到缺少id = 4
和id = 5
的项,因为在循环期间,尚未创建这些项的父项( id = 5
& id = 6
)。 我无法解决此问题,因为我不知道如何在子项之前遍历或转发列表以创建父项。 感谢帮助。 提前致谢。
更新
我为查询添加了一种情况,即id = 2
的项,这一次将项的parent_id更新为10( parent_id = 10
),因为我们没有id = 10
的项作为父项返回结果,因此此id = 2
项也将是根。
我的新代码基于Scott Hunter的指导,但是我仍然无法使其正常工作。 我一定在某个地方误解了:
new_dict = {}
for q in query:
q['Children'] = []
new_dict[q['id']] = q
for k, v in new_dict.iteritems():
print k, v
if v['parent_id'] is not None and v['parent_id'] in new_dict:
new_dict[k]['Children'].append(v)
print new_dict
更新2
现在,根据Scott Hunter的建议,使它可以工作,请参阅下面的代码。 但是,对于太多代码来说,它们看起来很丑陋,无论如何,我是否可以完善它? 非常感谢您的支持,只需再执行一步即可!
new_dict = {}
for q in query:
q['children'] = []
q['parent'] = 1
new_dict[q['id']] = q
for k, v in new_dict.iteritems():
p_id = v['parent_id']
for kk, vv in new_dict.iteritems():
if kk == p_id:
v['parent'] = 0
vv['children'].append(v)
results = []
for d_id, d_item in new_dict.iteritems():
if d_item['parent'] == 1:
results.append(d_item)
print results
这不需要递归。
首先创建一个节点字典,每个字典都使用id
作为键,每个节点一个,其中包括一个空的子列表。 然后,您可以扫描该词典,并将每个节点添加到其父级的子级列表中(跳过那些父级为None
的节点)。 扫描完成后,不是根节点的每个节点都将位于其父节点的子节点列表中,因此所有树都将完整。
Forrest的根是对父节点None
的节点。
这是我的解决方案:
#! /usr/bin/env python3
from pprint import pprint
query = [{'id': 1, 'desc': 'desc_father', 'parent_id': None}
,{'id': 2, 'desc': 'desc_child_1', 'parent_id': 1}
,{'id': 3, 'desc': 'desc_child_2', 'parent_id': 2}
,{'id': 4, 'desc': 'desc_child_5', 'parent_id': 5}
,{'id': 5, 'desc': 'desc_child_6', 'parent_id': 6}
,{'id': 6, 'desc': 'desc_child_1', 'parent_id': 1}]
def rec(query, parent):
parent['children'] = []
for item in query:
if item['parent_id'] == parent['id']:
parent['children'].append(item)
rec(query, item)
root = {'id': None}
rec(query, root)
pprint(root, indent=4)
它给了我输出(键混乱,但这就是您使用字典时得到的)
maurice@ubuntu:~/Dev/random$ python recursion_tree.py
{ 'children': [ { 'children': [ { 'children': [],
'desc': 'desc_child_2',
'id': 3,
'parent_id': 2}],
'desc': 'desc_child_1',
'id': 2,
'parent_id': 1},
{ 'children': [ { 'children': [ { 'children': [ ],
'desc': 'desc_child_5',
'id': 4,
'parent_id': 5}],
'desc': 'desc_child_6',
'id': 5,
'parent_id': 6}],
'desc': 'desc_child_1',
'id': 6,
'parent_id': 1}],
'desc': 'desc_father',
'id': 1,
'parent_id': None}
这甚至可以与多个根节点一起使用(尽管顶部会有一个id为None
的虚拟节点)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.