Skip to content
Advertisement

How to create a nest list or a tree view from a flat list based on value condition?

I am working on a problem that given a flat list of strings. But based on the name of the string I would like to create either a nested list, a dictionary or a Node class. Anything that can have a tree structure

The string looks something like:

['big_1', 'small_1', 'item_1', 'item_2', 'big_2', 'small_2', 'item_3']

This should be turned into something like

['big_1', ['small_1', ['item_1', 'item_2']], 'big_2', ['small_2', ['item_3']]]

or a nested dictionary:

{'big_1': { 'small_1': ['item_1', 'item_2']}, 'big_2': {'small_2': ['item_3']}}

The example has 3 levels but it can be of any amount of levels. I tried something like this because that is not correct:

x = ['a_1', 'b_1', 'b_2', 'a_2', 'b_3', 'a_3', 'b_4', 'b_5', 'b_6']

def category(input):
    return input.split('_')[0]

cats = list(dict.fromkeys([category(i) for i in x])) # order preserved unique set
results = {}

prev_cat = ''
result = []
index = 0
for item in x:
    if index == 0:
        result.append(item)
        index += 1
        prev_cat = category(item)
    else:
        curr_cat = category(item)
        if curr_cat == prev_cat:
            # Same category, append
            result.append(item)
        else:
            result.append([item])
print(result)

It returns ['a_1', ['b_1'], ['b_2'], 'a_2', ['b_3'], 'a_3', ['b_4'], ['b_5'], ['b_6']]

Any suggestion please?

Advertisement

Answer

I think I found a way to achieve this using recursion.

x = ["big_1", "small_1", "item_1", "item_2", "big_2", "small_2", "item_3"]


def category(input):
    return input.split("_")[0]


def parse(l):
    out = []
    cat = category(l[0])
    sublist = []
    for el in l:
        if category(el) != cat:
            sublist.append(el)
        else:
            if len(sublist) > 0:
                out.append(parse(sublist))
                sublist = []
            out.append(el)
    if len(sublist) > 0:
        out.append(parse(sublist))
        sublist = []
    return out


print(parse(x))

Basically what I do is recursively call the parse function each time I find a different level. The code is just a test and can definitely be improved.

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement