Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Insert/Add a json object in a dictionary at nested level dynamically

I am working on a script to generate some test data based on a json spec. The intention of this script is to construct a json object/python dict record

To simplify things, I am using a list items here that represents my source items, which also represent the path where the value should be inserted.

Here's my intended output -

{
    "access": {
        "device": {
            "java": {
                "version": "Test Data"
            },
            "python": {
                "version": "Test Data"
            }
        },
        "type": "Test Data"
    },
    "item1": 1,
    "item2": 0
}

I am able to build the nested objects but they are all getting inserted at first level of the dictionary instead.

How can I use dest_path to store the result in the intended location?

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
}
like image 348
Prashanth kumar Avatar asked Mar 23 '26 06:03

Prashanth kumar


1 Answers

To construct the record dictionary from the items list you can use 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)

Prints:

{
    "access": {
        "device": {
            "java": {"version": "Test Data"},
            "python": {"version": "Test Data"},
        },
        "type": "Test Data",
    },
    "item1": 1,
    "item2": 1,
}
like image 60
Andrej Kesely Avatar answered Mar 24 '26 19:03

Andrej Kesely



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!