繁体   English   中英

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

[英]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 = 4id = 5的项,因为在循环期间,尚未创建这些项的父项( id = 5id = 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM