Python – Dynamically inserts/adds json objects to nested level dictionaries

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,
}

Related Problems and Solutions