nicky_s
nicky_s

Reputation: 39

converting a flat list to a nested dictionary based on items from the list

For example, I have a flat list like this:

[' a',
'  aa1',
'   aaa1',
'   aaa2',
'   aaa3',
'   aaa4',
'   aaa5',
'  aa2',
'   aaa6',
'   aaa7',
'   aaa8',
'   aaa9',
'   aaa10',
' b',
'  bb1',
'   bbb1',
'   bbb2',
'   bbb3',
'  bb2',
'   bbb4',
'   bbb5',
'   bbb6',
'  bb3',
'   bbb7',
'   bbb8',
'   bbb9',
'   bbb10']

I need to convert to a nested dictionary like this:

{'a': {'aa1': ['aaa1', 'aaa2', 'aaa3', 'aaa4', 'aaa5'],
       'aa2': ['aaa6', 'aaa7', 'aaa8', 'aaa9', 'aaa10']},
 'b': {'bb1': ['bbb1', 'bbb2', 'bbb3'],
       'bb2': ['bbb4', 'bbb5', 'bbb6'],
       'bb3': ['bbb7', 'bbb8', 'bbb9', 'bbb10']}}

each item from the list concludes spaces, the item with only one space is assigned as the top key to the nested dictionary, the one with two spaces is assigned as the second level key to the previous item, and then with three spaces items are all the values for the previous key.

Upvotes: 2

Views: 220

Answers (1)

Moses Koledoye
Moses Koledoye

Reputation: 78556

I think the spaces only make the list awkward, you don't necessarily need them to achieve what you want.

First, strip all the spaces from the list items, then build the dictionary starting off from collections.defaultdict. The logic that does what you intended to do with the spaces is re.sub. Applied to clear out all the numbers, the length of the string after substitution can now be used to determine its position in the dictionary:

import re
from pprint import pprint
from collections import defaultdict

# remove all spaces from list items
lst = map(str.strip, lst)

d = defaultdict(lambda: defaultdict(list))

for i in lst:
    j = re.sub('\d+', '', i)
    if len(j) == 1:
        k1 = i
    elif len(j) == 2:
        k2 = i
    else:
        d[k1][k2].append(i)

pprint(d)
#{'a': {'aa1': ['aaa1', 'aaa2', 'aaa3', 'aaa4', 'aaa5'],
#       'aa2': ['aaa6', 'aaa7', 'aaa8', 'aaa9', 'aaa10']},
# 'b': {'bb1': ['bbb1', 'bbb2', 'bbb3'],
#       'bb2': ['bbb4', 'bbb5', 'bbb6'],
#       'bb3': ['bbb7', 'bbb8', 'bbb9', 'bbb10']}}

Upvotes: 2

Related Questions