Dynamically inserts/adds json objects to nested level dictionaries… here is a solution to the problem.
Dynamically inserts/adds json objects to nested level dictionaries
I’m writing a script to generate some test data according to the JSON spec. The purpose of this script is to construct a JSON object/Python Dict Record
To simplify things, I’m using a list items here to represent my source item, which also represents the path where the value should be inserted.
This is my expected output –
{
"access": {
"device": {
"java": {
"version": "Test Data"
},
"python": {
"version": "Test Data"
}
},
"type": "Test Data"
},
"item1": 1,
"item2": 0
}
I was able to build nested objects, but they were all inserted into the first level of the dictionary.
How do I use dest_path
to store results where I expect them?
Source:
import json
import random
def get_nested_obj(items: list):
"""
Construct a nested json object
"""
res = 'Test Data'
for item in items[::-1]:
res = {item: res}
return res
def get_dest_path(source_fields):
"""
Construct dest path where result from `get_nested_obj` should go
"""
dest_path = ''
for x in source_fields:
dest_path += f'[\'{x}\']'
return 'record'+dest_path
record = {}
items = ['access.device.java.version', 'access.device.python.version', 'access.type', 'item1', 'item2']
for item in items:
if '.' in item:
source_fields = item.split('.')
temp = record
for i, source_field in enumerate(source_fields):
if source_field in temp:
temp = temp[source_field]
continue
res = get_nested_obj(source_fields[i+1:])
dest_path = get_dest_path(source_fields[:i])
print(dest_path)
record[source_field] = res # Here's the problem. How to use dest_path here?
break
else:
record[item] = random.randint(0, 1)
print(json.dumps(record))
My output:
{
"access": {
"device": {
"java": {
"version": "Test Data"
}
}
},
"python": {
"version": "Test Data"
},
"type": "Test Data",
"item1": 1,
"item2": 0
}
Solution
To construct a record
dictionary from the items
list, you can use the next example:
import random
record = {}
items = [
"access.device.java.version",
"access.device.python.version",
"access.type",
"item1",
"item2",
]
for i in items:
i = i.split(".")
if len(i) == 1:
record[i[0]] = random.randint(0, 1)
else:
r = record
for v in i[:-1]:
r.setdefault(v, {})
r = r[v]
r[i[-1]] = "Test Data"
print(record)
Print:
{
"access": {
"device": {
"java": {"version": "Test Data"},
"python": {"version": "Test Data"},
},
"type": "Test Data",
},
"item1": 1,
"item2": 1,
}