I am trying to build a tree hierarchy with python lets say I have his structure, I need to be able to add more children dynamically to eg Bannana
. I think my question is a bit unclear
UPDATE: I need to create a structure like this, But The values will change so I need to create function to pass a int and create that amount of Apple(Children)
and to to do the same for Lemon and all the other children. Also the Apple node is Root Node.
Apple
Bannana
Lemon
Juice
Drink
Watermelon
Red
Round
But then I can Have a totally diffrent strucutre where eg
Apple
Bannana
Lemon
Juice
Drink
Watermelon
Red
Round
Json Ouptut would be
{
'Apple': 'Fruit',
'children': [{
'Bannana': 'fruit',
'children': None
}, {
'Lemon': 'Fruit',
'children': [{
'Juice': 'Food',
'children': [{
'Drink': 'Action',
'children': None
And so on...
How can make the hierarchy dynamic? For example the Number of rows under a specific parent?
I have tried something like that from an example I found
import collections
def add_element(root, path, data):
if len(path) == 1:
root[path[0]] = data
else:
add_element(root[path[0]], path[1:], data)
count = 1
tree = lambda: collections.defaultdict(tree)
root = tree()
n= 10
for i in range(1,n):
path_list= ['Apple', 'Lemon', 'Juice' + str(count)]
print (path_list)
count += 1
add_element(root,path_list, 1 )
print (root)
EDIT 1
As per the Answer I have modfied the code a bit
args = {'Apple': 'Apple', 'Lemon': 'Lemon', 'Juice': 'Juice', 'Drink': 'Drink'}
s = """
{Apple}
{Lemon}
{Juice}
{Drink}
""".format(**args)
def group_data(vals):
if len(vals) == 1:
return {vals[0]:'Fruit', 'Children':None}
new_data = [list(b) for _, b in itertools.groupby(vals, key=lambda x:bool(re.findall('^\s', x)))]
new_group = [[new_data[i], new_data[i+1]] for i in range(0, len(new_data), 2)]
result = []
for a, b in new_group:
result.extend([{i:'Fruit', 'Children':None} for i in a[:-1]])
result.append({a[-1]:'Fruit', 'Children':group_data([re.sub('^\s{3}', '', c) for c in b])})
return result
_new_data = [i.strip('\n') for i in filter(None, s.split('\n'))]
print(json.dumps(group_data(_new_data), indent=4))
this works fine but its still hardcoded which is not what im looking for.
You can analyze the whitespace before each fruit:
s = """
Apple
Bannana
Lemon
Juice
Drink
Watermelon
Red
Round
"""
import itertools, re
def group_data(vals):
if len(vals) == 1:
return {vals[0]:'Fruit', 'Children':None}
new_data = [list(b) for _, b in itertools.groupby(vals, key=lambda x:bool(re.findall('^\s', x)))]
new_group = [[new_data[i], new_data[i+1]] for i in range(0, len(new_data), 2)]
result = []
for a, b in new_group:
result.extend([{i:'Fruit', 'Children':None} for i in a[:-1]])
result.append({a[-1]:'Fruit', 'Children':group_data([re.sub('^\s{3}', '', c) for c in b])})
return result
_new_data = [i.strip('\n') for i in filter(None, s.split('\n'))]
import json
print(json.dumps(group_data(_new_data), indent=4))
Output:
[
{
"Apple": "Fruit",
"Children": [
{
"Bannana": "Fruit",
"Children": null
},
{
"Lemon": "Fruit",
"Children": [
{
"Juice": "Fruit",
"Children": [
{
"Drink": "Fruit",
"Children": {
"Watermelon": "Fruit",
"Children": null
}
}
]
},
{
"Red": "Fruit",
"Children": {
"Round": "Fruit",
"Children": null
}
}
]
}
]
}
]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.