python - 将dicts列表转换为层次结构/多个嵌套dicts - 订单问题

时间:2016-09-19 12:59:10

标签: python dictionary recursion parent-child

目前我有这些意见:

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 = 4id = 5的项目,因为在循环期间,尚未创建这些项目的父项(具有{{1的项目) }}& id = 5)。我在解决这个问题时遇到了困难,因为我不知道如何遍历或转发列表以在子项之前创建父项。感谢帮助。提前致谢。

已更新

我在一个案例中添加了我的查询,即id = 6项,这次项目更新为其parent_id为10(id = 2),因为我们没有项目parent_id = 10作为返回结果中的父项,因此此id = 10项也将是根。

我的新代码基于Scott Hunter的指导,但我仍然无法使其工作。我一定在某处误解了:

id = 2

更新完毕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 个答案:

答案 0 :(得分:2)

这不需要递归。

首先创建节点字典,每个项目使用None作为关键字,其中包含一个空的子项列表。然后,您可以扫描该字典,并将每个节点添加到其父节点的子节点列表中(跳过父节点为None的节点)。完成此扫描后,每个不是root的节点都将位于其父节点的子列表中,因此所有树都将完成。

forrest的根源是父节点Gson gson = new Gson(); String jsonOutput = "Your JSON String"; Type listType = new TypeToken<List<ApiResponse>>(){}.getType(); List<ApiResponse> posts = (List<ApiResponse>) gson.fromJson(jsonOutput, listType); 的节点。

答案 1 :(得分:2)

这将是我的解决方案:

#! /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的虚拟节点)