patternpythonMinor
Simplify the restructuring of json data
Viewed 0 times
therestructuringsimplifyjsondata
Problem
I am trying to ad nested to some flat data, which is nested.
Basically this code works the following way:
-
"taglevel":1 tags should be key of the array
-
"taglevel":2 or higher tags should be nested within an array and not be duplicated in its' array
-
If no "taglevel":1 exists add, it to a generic "NoLevel_1" array
The code is still clunky and I feel there is a much cleaner way to achieve this.
The data:
```
json_data = [{
"title": "Random",
"tag": [
{
"name": "Fruit",
"taglevel": 1
},
{
"name": "Apple",
"taglevel": 2
}
]
},
{
"title": "Other",
"tag": [
{
"name": "Fruit",
"taglevel": 1
Basically this code works the following way:
-
"taglevel":1 tags should be key of the array
-
"taglevel":2 or higher tags should be nested within an array and not be duplicated in its' array
-
If no "taglevel":1 exists add, it to a generic "NoLevel_1" array
The code is still clunky and I feel there is a much cleaner way to achieve this.
import json
generic = []
result = []
for i in json_data:
if any(d['taglevel'] == 1 for d in i['tag']):
tag_data = {}
tag_child = []
for tag in i['tag']:
if tag['taglevel'] == 1:
tag_data['name'] = tag['name']
tag_data['taglevel'] = 1
else:
tag_child.append(tag)
filtered = {tuple((k, d[k]) for k in sorted(d) if k in ['name']): d for d in tag_child}
tag_data['tag_child'] = list(filtered.values())
if any(d['name'] == tag_data['name'] for d in result):
for t in result:
if t['name'] == tag_data['name']:
t['tag_child'] = t['tag_child'] + tag_child
filtered = {tuple((k, d[k]) for k in sorted(d) if k in ['name']): d for d in t['tag_child']}
t['tag_child'] = list(filtered.values())
else:
result.append(tag_data)
else:
for tag in i['tag']:
generic.append(tag)
tag_data = {}
tag_data['name'] = 'NoLevel1'
tag_data['taglevel'] = 1
tag_data['tag_child'] = generic
result.append(tag_data)
print json.dumps(result, indent=4, sort_keys=True)The data:
```
json_data = [{
"title": "Random",
"tag": [
{
"name": "Fruit",
"taglevel": 1
},
{
"name": "Apple",
"taglevel": 2
}
]
},
{
"title": "Other",
"tag": [
{
"name": "Fruit",
"taglevel": 1
Solution
Well you may or may not considered this a simplification but this is how I would approach it.
You could use a
You can't store a
We then reformat
You could use
You could use a
set to handle the duplication part. You can't store a
dict in a set though so we need to create a tuple from the values. (It looks like you're doing something similar with filtered)We then reformat
result to get the desired final structure.from collections import defaultdict
result = defaultdict(set)
for item in json_data:
parent = {'name': 'NoLevel_1'}
children = []
for tag in item['tag']:
if tag['taglevel'] == 1:
parent = tag
else:
children.append((tag['taglevel'], tag['name']))
result[parent['name']].update(children)
result = [
{
'name': parent,
'tag_child': [
{'name': name, 'taglevel': taglevel} for taglevel, name in tags
],
'taglevel': 1,
} for parent, tags in result.items()
]You could use
next() and a list comprehension for the parent and child creation however it iterates the tags twice and may not be as "readable"parent = next((tag for tag in item['tag'] if tag['taglevel'] == 1), {'name': 'NoLevel_1'})
children = [(tag['taglevel'], tag['name']) for tag in item['tag'] if tag['taglevel'] != 1]Code Snippets
from collections import defaultdict
result = defaultdict(set)
for item in json_data:
parent = {'name': 'NoLevel_1'}
children = []
for tag in item['tag']:
if tag['taglevel'] == 1:
parent = tag
else:
children.append((tag['taglevel'], tag['name']))
result[parent['name']].update(children)
result = [
{
'name': parent,
'tag_child': [
{'name': name, 'taglevel': taglevel} for taglevel, name in tags
],
'taglevel': 1,
} for parent, tags in result.items()
]parent = next((tag for tag in item['tag'] if tag['taglevel'] == 1), {'name': 'NoLevel_1'})
children = [(tag['taglevel'], tag['name']) for tag in item['tag'] if tag['taglevel'] != 1]Context
StackExchange Code Review Q#161090, answer score: 4
Revisions (0)
No revisions yet.