Home > front end >  Concatenate nested same key values in sub objects in python dictionary
Concatenate nested same key values in sub objects in python dictionary

Time:09-16

I have this python dictionary that contains inside some nested objects:

Input

 {
            "data": [
                {
                    "name": "default",
                    "type": "pkg"
                },
                {
                    "name": "name1",
                    "subobj": [
                        {
                            "name": "subname1",
                            "subobj": [
                                {
                                    "name": "sub-subname1",
                                    "type": "pkg"
                                },
                                {
                                    "name": "sub-subname2",
                                    "type": "pkg"
                                }
                            ],
                            "type": "folder"
                        }
                    ],
                    "type": "folder"
                }
            ]
}

I need to recursively create a list that concatenates the "name" keys (maintaining the hierarchy) like the following:

Output

  • default

  • name1/subname1/sub-subname1

  • name1/subname1/sub-subname2

    How Could I achieve this Output taking in consideration that could be there infinite nested object in subobj ?

CodePudding user response:

You can do this with a rather simple recursive function, building up a prefix string of parent names and finally yielding the combined names for all the pkg items.

def get_names(lst, prefix=""):
    for d in lst:
        if d["type"] == "pkg":
            yield f"{prefix}{d['name']}"
        elif d["type"] == "folder":
            yield from get_names(d["subobj"], f"{prefix}{d['name']}/")

Then call this for the data["data"] item (data being your full nested dictionary):

for name in get_names(data["data"]):
    print(name)

Output:

default
name1/subname1/sub-subname1
name1/subname1/sub-subname2

CodePudding user response:

I think this function should make the job

from typing import Union

def get_values(obj, only_add: str, prev_key: str = '') -> list:
    keys = []
    if type(obj) is dict:
        for key, item in obj.items():
            if key == only_add:
                keys.append(f"{prev_key}/{item}")
                prev_key = f"{prev_key}/{item}"
                
            elif isinstance(item, (list, dict)):
                keys.extend(get_values(item, only_add, prev_key))
    
    elif type(obj) is list:
        for item in obj:
            keys.extend(get_values(item, only_add, prev_key))
    return keys

Output of the function on your data

get_values(data, only_add="name")
>>> ['/default',
 '/name1',
 '/name1/subname1',
 '/name1/subname1/sub-subname1',
 '/name1/subname1/sub-subname2']

  • Related