简体   繁体   中英

How to return all paths from a dictionary?

Lets say i have this dictionary

obj = {'layerA1':'string','layerA2':{'layerB1':{'layerC1':{},'layerC2':{}},
                                     'layerB2':{}}}

i would need to return

['layerA2','layberB1','layerC1']
['layerA2','layerB1','layerC2']
['layerA2','layerB2']

It should work regardless of how deep the dictionary gets. Currently trying with some recursive functions but i can't seem to get it right. What i currently have is this:

obj = {'layerA1':'string','layerA2':{'layerB1':{'layerC1':{},'layerC2':{}},
                                     'layerB2':{}}}


hierarchy_list = []
def find_hierachy(param):
    some_list = []
    for key, value in param.items():
        if type(param[key]) is dict:
            some_list.append(key)
            hierarchy_list.append(some_list)
            find_hierachy(param[key])

find_hierachy(obj)
print(hierarchy_list)

[['layerA2'], ['layerB1', 'layerB2'], ['layerC1', 'layerC2'], ['layerC1', 'layerC2'], ['layerB1', 'layerB2']]

I don't know how to get it to return each hierarchical path made of keys

As you noticed in your code, you need to keep track of the path you have taken sofar, this is often referred to as the prefix. By storing the prefix and passing it along, we can keep track of the previous keys. An important thing to keep in mind is that default variables in python should be immutable (tuples) unless you know what happens with mutable objects while using recursion.

answer = []
def hierarchy(dictionary, prefix=()):
    for key, value in dictionary.items():
        if isinstance(value, dict) and value:
            hierarchy(value, (*prefix, key))
        else:
            answer.append((*prefix, key))

If you want the final answer to be a list, you can loop over the answers and cast them to a list, or send the list as prefix. This requires us to copy the list to the next level of the hierarchy. Which is done using [*prefix, key] which makes a new copy of the list.

obj = {'layerA1': 'string', 'layerA2': {'layerB1': {'layerC1': {}, 'layerC2': {}},
                                        'layerB2': {}}}

if __name__ == '__main__':

    answer = []
    def hierarchy(dictionary, prefix=None):
        prefix = prefix if prefix is not None else []
        for key, value in dictionary.items():
            if isinstance(value, dict) and value:
                hierarchy(value, [*prefix, key])
            else:
                answer.append([*prefix, key])


    hierarchy(obj)
    print(answer)

Output

[['layerA1'], ['layerA2', 'layerB1', 'layerC1'], ['layerA2', 'layerB1', 'layerC2'], ['layerA2', 'layerB2']]

Note:

Type checking can be done using isinstance(obj, type) , which is the preferred way above type(obj) is type .

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