Reputation: 91
I'm getting values in the below format
/a/b/c/d="value1"
/a/b/e/f="value2"
I want these values in the below format.
{
"a": {
"b": {
{
"c": {
"d": "value1"
}
},
{
"e" {
"f": "value2"
}
}
}
}
}
Are there any built-in functions in python that can do this job as I could a["b"]["c"]["d"]
kind of structure is not possible in the python dictionary?
Upvotes: 0
Views: 395
Reputation: 91
As suggested in above msgs, I created a recursive function which split path["a/b/c"] and it's value["value1"] and create an output_dict will store all the values in json/dict format.
resources={"/a/b/c/d":"value1","/a/b/e/f":"value2"}
output_dict = {}
def create_nested_dict(path, value, output_dict):
"""Create a nested dictionary from the given path and value."""
keys = path.split("/")
if len(keys) == 1:
output_dict[keys[0]] = value
else:
key = keys[0]
if key not in output_dict:
output_dict[key] = {}
create_nested_dict("/".join(keys[1:]), value, output_dict[key])
for resource in resources:
for path,value in resource.items():
create_nested_dict(path[1:], value, output_dict)
Upvotes: 0
Reputation: 189397
Built-in no, but you can reduce
each of these expressions to a dictionary and then get their union.
from functools import reduce
data = """
/a/b/c/d="value1"
/a/b/e/f="value2"
"""
exp = dict()
for pathexp in data.strip().splitlines():
# skip past first "/" to avoid getting an empty element
path, value = pathexp.lstrip("/").rsplit("=", 1)
exp.update(
reduce(lambda x, y: {y: x}, reversed(path.split("/")),
value.strip('"')))
print(exp)
If you really wanted to, you could fold this into a one-liner with another reduce
instead of the loop; but unless you are really into functional programming, this is already rather dense.
Upvotes: 1
Reputation: 3462
Feels a bit hacky, but if you want to go with the a["b"]["c"]["d"]
route, you could use collections.defaultdict
to do it.
from collections import defaultdict
def defaultdict_factory():
return defaultdict(defaultdict)
a = defaultdict(defaultdict_factory)
a["b"]["c"]["d"] = "value1"
Upvotes: 1