0

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 ?

2 Answers 2

3

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
Sign up to request clarification or add additional context in comments.

Comments

1

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']

6 Comments

Not quite, i just need the "name" keys' values :-)
Have you read the output requested ? @Bass asked for >>> ["/default", "/name1/subname1/sub-subname1", '/name1/subname1/sub-subname2", ] not >>> ['/data/name --> default', '/data/name --> name1', '/data/subobj/name --> subname1', '/data/subobj/subobj/name --> sub-subname1', '/data/subobj/subobj/name --> sub-subname2'] '/data/subobj/subobj/name --> sub-subname2']
This combines all the direct parent keys, but OP wants to combine all the name values in the parent dicts.
Also, did not check in detail, but why the instanceof check after the type checks? You already have cases for all types on the top level, so can't you just call the function again for all children?
@tobias_k, thank for your comments. I really misunderstood the question. I have finally corrected my answer. Thanks again
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.