Let's say we want to create/maintain a dict with below key structure
{
"a": {"bb": {"01": "some value 01",
"02": "some value 02",
} },
}
We use dpath .new() as below to do this
import dpath
d=dict() ; print(d) # d={}
dpath.new(d,'a/bb/00/c', '00val') ; print(d) # d={'a': {'bb': [{'c': '00val'}]}}
# d # NOTE this will set :bb as a list, and set at bb[00] ie idx=0 of list bb
# d # what we want instead is d={'a': {'bb': {'00': {'c': '00val'} }}}
# d # what we want is NOT d={'a': {'bb': [ {'c': '00val'} ]}}
So when using 00
in the path, dpath translate it into list index at 0
instead of dict key 00
The question is how to set key as 00
? Currently I have to dodge it by setting prefix s
ie s00
s01
s02
I traced into the source, and noticed that it calls a Creator, documented in the function as:
creator allows you to pass in a creator method that is
responsible for creating missing keys at arbitrary levels of
the path (see the help for dpath.path.set)
I copied _default_creator from dpath.segments, and just eliminated the code that treats int values as a list index. Here's the quick and dirty version:
import dpath
from dpath.segments import extend
from typing import Sequence, MutableSequence
def my_creator(current, segments, i, hints):
segment = segments[i]
length = len(segments)
if isinstance(current, Sequence):
segment = int(segment)
if isinstance(current, MutableSequence):
extend(current, segment)
# Infer the type from the hints provided.
if i < len(hints):
current[segment] = hints[i][1]()
else:
# deleted the array stuff here
current[segment] = {}
d = dict()
dpath.new(d, r'a/bb/00/c', '00val', creator=my_creator)
print(d)
output
{'a': {'bb': {'00': {'c': '00val'}}}}