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.