简体   繁体   中英

Nesting python dictionary

Hi everybody I'm working on this for few hours but it seems I'm not able to finish this work.

I have this json structure:

{
    "1": {
        "name": "foo",
        "color": "black",
        "children": ["2", "3"]
     },
    "2": {
        "name": "foo2",
        "color": "green",
        "children": []
     },
    "3": {
        "name": "foo3",
        "color": "yellow",
        "children": ["4"]
     },
    "4": {
        "name": "foo4",
        "color": "purple",
        "children": []
     }
}

and i would like to convert this in the next json structure using python dictionary:

{
    "foo":{
        "color":"black",
        "children":{
            "foo2":{
                "color":"green",
                "children":{}
            },
            "foo3":{ 
                "color":"yellow",
                "children":{
                    "foo4":{
                        "color":"purple", 
                        "children":{}
                        }
                }
            }
        }
    }
}

can someone help me, please?

No recursion needed. Try this (with s being your original string):

>>> import json
>>> data = json.loads(s)
>>> for v in data.values():
    v['children'] = {data[c]['name']:data[c] for c in v['children']}


>>> d = {data['1']['name']:data['1']}
>>> for v in data.values():
    del v['name']


>>> print(json.dumps(d, indent=4))
{
    "foo": {
        "color": "black", 
        "children": {
            "foo2": {
                "color": "green", 
                "children": {}
            }, 
            "foo3": {
                "color": "yellow", 
                "children": {
                    "foo4": {
                        "color": "purple", 
                        "children": {}
                    }
                }
            }
        }
    }
}

So one pass over the data to replace the 'pointers' to the actual children, then a second pass to get rid of the names. All the dictionaries/lists are mutated in place so the linked up children continue to work.

In first place, you have to know that dict is not ordered, so you can't know that "1" will be first key you will get while iterating. If always "1" is the first element, then:

dict_to_convert = {
    "1": {
        "name": "foo",
        "color": "black",
        "children": ["2", "3"]
    },
    "2": {
        "name": "foo2",
        "color": "green",
        "children": []
    },
    "3": {
        "name": "foo3",
        "color": "yellow",
        "children": ["4"]
    },
    "4": {
        "name": "foo4",
        "color": "purple",
        "children": []
    }
}


def convert_dict(dict_to_convert, key=None):
    if key is not None:
        new_dict = {}
        for key in dict_to_convert[key]["children"]:
            new_dict[dict_to_convert[key]["name"]] = {}
            new_dict[dict_to_convert[key]["name"]]["color"] = dict_to_convert[key]["color"]
            new_dict[dict_to_convert[key]["name"]]["children"] = convert_dict(dict_to_convert, key)
    else:
        new_dict = {}
        new_dict[dict_to_convert["1"]["name"]] = {}
        new_dict[dict_to_convert["1"]["name"]]["color"] = dict_to_convert["1"]["color"]
        new_dict[dict_to_convert["1"]["name"]]["children"] = convert_dict(dict_to_convert, "1")
    return new_dict


converted_dict = convert_dict(dict_to_convert)
print converted_dict

I checked it, it works.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM