How would I group JSON objects by id’s to make a nested JSON in Python? The JSON is structured this way:
JavaScript
x
31
31
1
[{
2
"id": "4",
3
"title": "Part 4",
4
"children": {}
5
},{
6
"id": "4.1.",
7
"title": "Section 4.1. Transition Rule",
8
"children": {}
9
},
10
{
11
"id": "4.1.1.",
12
"title": "4.1.1. Transition, January 2014",
13
"children": {}
14
},
15
{
16
"id": "4.1.1.1.",
17
"title": "4.1.1.1. Transition Rule",
18
"children": {}
19
},
20
{
21
"id": "4.1.2.",
22
"title": "4.1.2. Transition, January 2015",
23
"children": {}
24
},
25
{
26
"id": "4.1.2.1.",
27
"title": "4.1.2.1. Transition Rule",
28
"children": {}
29
},
30
]]
31
The goal is to have a tree structure where each object(section) contains all its subsections going from 4 to 4.1 > 4.1.1 > 4.1.1.1.
The snippet of the required output is below:
JavaScript
1
33
33
1
[
2
{
3
"id":"4",
4
"title":"Part 4",
5
"children":{
6
{
7
"id":"4.1.",
8
"title":"Section 4.1. Transition Rule",
9
"children":{
10
{
11
"id":"4.1.1.",
12
"title":"4.1.1. Transition, January 2014",
13
"children":{
14
{
15
"id":"4.1.1.1.",
16
"title":"4.1.1.1. Transition Rule",
17
"children":{
18
19
}
20
}
21
}
22
},
23
{
24
"id":"4.1.2.",
25
"title":"4.1.2. Transition, January 2015",
26
"children":{
27
{
28
"id":"4.1.2.1.",
29
"title":"4.1.2.1. Transition Rule",
30
"children":{
31
32
33
Advertisement
Answer
You can use recursion:
JavaScript
1
16
16
1
from collections import defaultdict
2
def get_tree(d):
3
_d, r = defaultdict(list), []
4
for i in d:
5
_d[i['key'][0]].append({**i, 'key':i['key'][1:]})
6
for b in _d.values():
7
j, k = [l for l in b if not l['key']], [l for l in b if l['key']]
8
if j:
9
r.extend([{**{x:y for x, y in i.items() if x != 'key'}, 'children':get_tree(k)} for i in j])
10
else:
11
r.extend(get_tree(k))
12
return r
13
14
15
data = [{'id': '4', 'title': 'Part 4', 'children': {}}, {'id': '4.1.', 'title': 'Section 4.1. Transition Rule', 'children': {}}, {'id': '4.1.1.', 'title': '4.1.1. Transition, January 2014', 'children': {}}, {'id': '4.1.1.1.', 'title': '4.1.1.1. Transition Rule', 'children': {}}, {'id': '4.1.2.', 'title': '4.1.2. Transition, January 2015', 'children': {}}, {'id': '4.1.2.1.', 'title': '4.1.2.1. Transition Rule', 'children': {}}, {'id': '4.1.3.', 'title': '4.1.3. Transition, January 2017', 'children': {}}]
16
JavaScript
1
3
1
import json
2
print(json.dumps(get_tree([{**i, 'key':[*filter(None, i['id'].split('.'))]} for i in data]), indent=4))
3
Output:
JavaScript
1
42
42
1
[
2
{
3
"id": "4",
4
"title": "Part 4",
5
"children": [
6
{
7
"id": "4.1.",
8
"title": "Section 4.1. Transition Rule",
9
"children": [
10
{
11
"id": "4.1.1.",
12
"title": "4.1.1. Transition, January 2014",
13
"children": [
14
{
15
"id": "4.1.1.1.",
16
"title": "4.1.1.1. Transition Rule",
17
"children": []
18
}
19
]
20
},
21
{
22
"id": "4.1.2.",
23
"title": "4.1.2. Transition, January 2015",
24
"children": [
25
{
26
"id": "4.1.2.1.",
27
"title": "4.1.2.1. Transition Rule",
28
"children": []
29
}
30
]
31
},
32
{
33
"id": "4.1.3.",
34
"title": "4.1.3. Transition, January 2017",
35
"children": []
36
}
37
]
38
}
39
]
40
}
41
]
42