Skip to main content
 首页 » 编程设计

python之如何从带有parent_id的dict创建带有children的dict

2025年05月04日17tuyile006

如何从这个字典中得到:

    cats = [ 
    {'parent_id': False, 'id': 1, 'title': u'All'}, 
    {'parent_id': False, 'id': 2, 'title': u'Toys'}, 
    {'parent_id': 2, 'id': 3, 'title': u'Toypads'}, 
    {'parent_id': 3, 'id': 4, 'title': u'Green'}, 
    ] 

是这样的吗?

cats = [ 
{'parent_id': False, 'id': 1, 'title': u'All'}, 
{'parent_id': False, 
 'children': [{'parent_id': 2, 
               'children': [{'parent_id': 3, 'id': 4, 
                             'title': u'Green'}], 
               'id': 3, 'title': u'Toypads'}, 
              [{'parent_id': 3, 'id': 4, 'title': u'Green'}]], 
 'id': 2, 'title': u'Toys'} 
] 

我需要它在 Jinja2 中构建菜单\子菜单。 我写了一个非常糟糕的代码。这将是一个更优雅的解决方案。

    q = dict(zip([i['id'] for i in cats], cats)) 
 
    from collections import defaultdict 
    parent_map = defaultdict(list) 
 
    for item in q.itervalues(): 
        parent_map[item['parent_id']].append(item['id']) 
 
    def tree_level(parent): 
        for item in parent_map[parent]: 
            yield q[item] 
            sub_items = list(tree_level(item)) 
            if sub_items: 
                for ca in cats: 
                    if ca['id'] == item: 
                        cats[cats.index(ca)]['children'] = sub_items 
                        for s_i in sub_items: 
                            try: 
                                for ca_del_child in cats: 
                                    if ca_del_child['id'] == s_i['id']: 
                                        del cats[cats.index(ca_del_child)] 
                            except: 
                                pass 
                yield sub_items 
    for i in list(tree_level(False)): 
        pass 

请您参考如下方法:

这是一个相当简洁的解决方案:

cats = [{'parent_id': False, 'id': 1, 'title': u'All'}, 
        {'parent_id': False, 'id': 2, 'title': u'Toys'}, 
        {'parent_id': 2, 'id': 3, 'title': u'Toypads'}, 
        {'parent_id': 3, 'id': 4, 'title': u'Green'},] 
 
cats_dict = dict((cat['id'], cat) for cat in cats) 
 
for cat in cats: 
    if cat['parent_id'] != False: 
        parent = cats_dict[cat['parent_id']] 
        parent.setdefault('children', []).append(cat) 
 
cats = [cat for cat in cats if cat['parent_id'] == False] 

请注意,与 False 的比较通常不是必需的,但如果您有一只 id 或 parent_id 为 0 的猫,则应在此处使用它们。在这种情况下,对于没有 parent 的猫,我会使用 None 而不是 False。