I second the people saying that indexing a dictionary by position is not the natural way, but it is possible since python3.7 as the dict is insertion-ordered as a guaranteed language-feature in python.
This is my working example, the indices are different than your schematic, but it made more sense for me to index it like that. It makes use of recursive traversing of the data by the given indices and then depending on the operation removing, inserting or returning the nested data.
The insertion of data makes use of the mentioned ordering by insertion in python.
data.update(dict(**insert, **after))
- It leaves the data before the insertion as is (so it is older and thus staying in front)
- Then it updates the inserted data
- And last the data after the inserted data (making it the oldest and thus at the back).
from copy import deepcopy
import itertools
import json
def traverse(data, index_list):
index = index_list.pop()
if index_list:
nested_data = list(data.values())[index]
return traverse(nested_data, index_list)
return data, index
def insert(data, data_insert, index_list):
data, index = traverse(data, index_list)
after = dict(itertools.islice(data.items(), index)) or None
data.update(dict(**data_insert, **after))
def remove(data, index_list):
key, data = get(data, index_list)
return {key: data.pop(key)}
def get(data, index_list):
data, index = traverse(data, index_list)
key = list(data.keys())[index]
return key, data
def run_example(example_name, json_in, index_str, operation, data_insert=None):
print("-" * 40 + f"\n{example_name}")
print(f"json before {operation} at {index_str}:")
print(json.dumps(json_in, indent=2, sort_keys=False))
index_list = [int(idx_char) for idx_char in index_str.split(".")]
if operation == "insert":
json_out = insert(json_in, data_insert, index_list)
elif operation == "remove":
json_out = remove(json_in, index_list)
elif operation == "get":
key, data = get(json_in, index_list)
json_out = {key: data[key]}
else:
raise NotImplementedError("Not a valid operation")
print(f"json after:")
print(json.dumps(json_in, indent=2, sort_keys=False))
print(f"json returned:")
print(json.dumps(json_out, indent=2, sort_keys=False))
json_data = {
"field1": "value1",
"field2": {
"field3": "val3",
"field4": "val4"
}
}
run_example("example 1", deepcopy(json_data), "1", "remove")
run_example("example 2", json_data, "2", "insert", {"field2x": {"field3x": "val3x", "field4x": "val4x"}})
run_example("example 3", json_data, "2", "get")
run_example("example 4", json_data, "2.2", "insert", {"field2xx": {"field3xx": "val3xx", "field4xx": "val4xx"}})
run_example("example 5", json_data, "2", "remove")
This gives the following output:
----------------------------------------
example 1
json before remove at 1:
{
"field1": "value1",
"field2": {
"field3": "val3",
"field4": "val4"
}
}
json after:
{
"field1": "value1"
}
json returned:
{
"field2": {
"field3": "val3",
"field4": "val4"
}
}
----------------------------------------
example 2
json before insert at 2:
{
"field1": "value1",
"field2": {
"field3": "val3",
"field4": "val4"
}
}
json after:
{
"field1": "value1",
"field2": {
"field3": "val3",
"field4": "val4"
},
"field2x": {
"field3x": "val3x",
"field4x": "val4x"
}
}
json returned:
null
----------------------------------------
example 3
json before get at 2:
{
"field1": "value1",
"field2": {
"field3": "val3",
"field4": "val4"
},
"field2x": {
"field3x": "val3x",
"field4x": "val4x"
}
}
json after:
{
"field1": "value1",
"field2": {
"field3": "val3",
"field4": "val4"
},
"field2x": {
"field3x": "val3x",
"field4x": "val4x"
}
}
json returned:
{
"field2x": {
"field3x": "val3x",
"field4x": "val4x"
}
}
----------------------------------------
example 4
json before insert at 2.2:
{
"field1": "value1",
"field2": {
"field3": "val3",
"field4": "val4"
},
"field2x": {
"field3x": "val3x",
"field4x": "val4x"
}
}
json after:
{
"field1": "value1",
"field2": {
"field3": "val3",
"field4": "val4"
},
"field2x": {
"field3x": "val3x",
"field4x": "val4x",
"field2xx": {
"field3xx": "val3xx",
"field4xx": "val4xx"
}
}
}
json returned:
null
----------------------------------------
example 5
json before remove at 2:
{
"field1": "value1",
"field2": {
"field3": "val3",
"field4": "val4"
},
"field2x": {
"field3x": "val3x",
"field4x": "val4x",
"field2xx": {
"field3xx": "val3xx",
"field4xx": "val4xx"
}
}
}
json after:
{
"field1": "value1",
"field2": {
"field3": "val3",
"field4": "val4"
}
}
json returned:
{
"field2x": {
"field3x": "val3x",
"field4x": "val4x",
"field2xx": {
"field3xx": "val3xx",
"field4xx": "val4xx"
}
}
}