I want to take a list like the following:
groups = ["foo", "bar", "foo::fone", "foo::ftwo", "foo::ftwo::ffone"]
And convert it into a nested list, probably in the following format, but I'm open to suggestions:
groups_sorted = [{
"name":"foo",
"children": [
{
"name": "foo::fone",
"children": [ ... ]
}, ...
]
}, ...
]
So that the list is sorted using a hierarchy split on ::. I need each of the children keys to be lists themselves as the original order of the list is important.
I've played around for a few hours and been able to create a recursive dictionary starting from a single top node, but I couldn't do the last bit. Find my workings below:
def children_of(node, candidates):
children = []
remainder = []
for c in candidates:
sub = node + "::"
if c.startswith(sub):
try:
c[len(sub):].index("::") # any more separators = not a child
remainder.append(c)
except ValueError: # a child
children.append(c)
else: #not related
remainder.append(c)
return children, remainder
def sortit(l):
if l:
el = l.pop(0)
children, remainder = children_of(el,l)
if children:
return { "name": el,
"children": [sortit([c]+remainder) for c in children]
}
else:
return { "name": el }
Edit: @Thijs van Dien's solution is really good but I need 2.6 compatibility which prevents me some using OrderDicts.