Вы можете использовать рекурсию с collections.defaultdict
:
from collections import defaultdict
def to_tree(d):
_d = defaultdict(list)
for a, *b in d:
_d[a].append(b)
return [{'name':a, 'children':to_tree(k)} if (k:=list(filter(None, b))) else \
{'name':a} for a, b in _d.items()]
data = [['root','Parent1','Children1','Grand Childern 1','Great Grand Childern 1'],['root','Parent1','Children2','Grand Childern 1','Great Grand Childern 1'],['root','Parent1','Children2','Grand Childern 2','Great Grand Childern 1'],['root','Parent2','Children1','Grand Childern 1','Great Grand Childern 1'],['root','Parent2','Children2','Grand Childern 1','Great Grand Childern 1']]
import json
print(json.dumps(to_tree(data), indent=4))
Вывод:
[
{
"name": "root",
"children": [
{
"name": "Parent1",
"children": [
{
"name": "Children1",
"children": [
{
"name": "Grand Childern 1",
"children": [
{
"name": "Great Grand Childern 1"
}
]
}
]
},
{
"name": "Children2",
"children": [
{
"name": "Grand Childern 1",
"children": [
{
"name": "Great Grand Childern 1"
}
]
},
{
"name": "Grand Childern 2",
"children": [
{
"name": "Great Grand Childern 1"
}
]
}
]
}
]
},
{
"name": "Parent2",
"children": [
{
"name": "Children1",
"children": [
{
"name": "Grand Childern 1",
"children": [
{
"name": "Great Grand Childern 1"
}
]
}
]
},
{
"name": "Children2",
"children": [
{
"name": "Grand Childern 1",
"children": [
{
"name": "Great Grand Childern 1"
}
]
}
]
}
]
}
]
}
]
Решение без Python3 .8 выражения присваивания:
from collections import defaultdict
def to_tree(d):
_d = defaultdict(list)
for a, *b in d:
_d[a].append(b)
vals = [[a, list(filter(None, b))] for a, b in _d.items()]
return [{'name':a, 'children':to_tree(b)} if b else {'name':a} for a, b in vals]