简体   繁体   中英

How to build a recursive dictionary tree from an ordered adjacency list

I've been trying to figure this out all day and Im at my wits end. Maybe I'm just getting to old for this.

I'm trying to build a tree for the load_bulk feature on django-treebeard as specified here

To save you looking, it should look like this:

data = [{'data':{'desc':'1'}},
         {'data':{'desc':'2'}, 'children':[
          {'data':{'desc':'21'}},
          {'data':{'desc':'22'}},
          {'data':{'desc':'23'}, 'children':[
            {'data':{'desc':'231'}},
          ]},
          {'data':{'desc':'24'}},
        ]},
        {'data':{'desc':'3'}},
        {'data':{'desc':'4'}, 'children':[
          {'data':{'desc':'41'}},
        ]},
]

'data' holds the record, and if it has children, 'children' is a list of more 'data' dicts (that can also contain a list of children and so on recursively)

I get the data as an ordered list (ordered as in depth first, not by id):

eg:

[
    {'id': 232, 'name': 'jon', 'parent': 'None'}
    {'id': 3522, 'name': 'dave', 'parent': '232'}
    {'id': 2277, 'name': 'alice', 'parent': '3522'}
    {'id': 119, 'name': 'gary', 'parent': '232'}
    {'id': 888, 'name': 'gunthe', 'parent': '119'}
    {'id': 750, 'name': 'beavis', 'parent': 'None'}
    {'id': 555, 'name': 'urte', 'parent': '750'}
]

How can I transform it into a treebeard compliant dictionary that would look like this (typo's excepted):

[
{'data': {'id': 232, 'name': 'jon', 'parent': 'None'},
 'children': [
              {'data': {'id': 3522, 'name': 'dave', 'parent': '232'},
               'children': [
                            {'data': {'id': 2277, 'name': 'alice', 'parent': '3522'}}
                           ]
              }
              {'data': {'id': 119, 'name': 'gary', 'parent': '232'},
               'children': [
                            {'id': 888, 'name': 'gunthe', 'parent': '119'}
                           ]
              }
             ]
{'data': {'id': 750, 'name': 'beavis', 'parent': 'None'},
 'children': [
              {'id': 555, 'name': 'urte', 'parent': '750'}
             ]
}

]

I guess I need some kind of recursion function seeing as its a recursive structure but all my attempts have failed. My brain doesnt do recursion so good.

I did a lot of searching and found mostly solutions pertaining to lists or other structures that i cant mould to fit. I'm a relative noob. ps i had more fun manually typing out the example than i did the rest of day (apart from dinner time).

Maybe there are better ways, but here is one solution:

users = [
    {
        'id': 232,
        'name': 'jon',
        'parent': None
    },
    {
        'id': 3522,
        'name': 'dave',
        'parent': 232
    },
    {
        'id': 2277,
        'name': 'alice',
        'parent': 3522
    },
    {
        'id': 119,
        'name': 'gary',
        'parent': 232
    },
    {
        'id': 888,
        'name': 'gunthe',
        'parent': 119
    },
    {
        'id': 750,
        'name': 'beavis',
        'parent': None
    },
    {
        'id': 555,
        'name': 'urte',
        'parent': 750
    }
]

users_map = {}
for user in users:
    users_map[user['id']] = user

users_tree = []
for user in users:
    if user['parent'] is None:
        users_tree.append(user)
    else:
        parent = users_map[user['parent']]
        if 'childs' not in parent:
            parent['childs'] = []
        parent['childs'].append(user)

print(users_tree)

#user as {data: user, childs: []}

users_map = {}
for user in users:
    users_map[user['id']] = {'data': user, 'childs': []}

users_tree = []
for user in users:
    if user['parent'] is None:
        users_tree.append(users_map[user['id']])
    else:
        parent = users_map[user['parent']]
        parent['childs'].append(users_map[user['id']])

print(users_tree)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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