Deepakvg
Deepakvg

Reputation: 91

How to convert path into json in python?

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

Answers (3)

Deepakvg
Deepakvg

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

tripleee
tripleee

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

Tzane
Tzane

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

Related Questions