Home > database >  Check every layer of nested dict for two specific keys and return key value pair
Check every layer of nested dict for two specific keys and return key value pair

Time:08-24

I have already tried numerous approaches, but unfortunately do not come to any useful result. I have the following problem: I have a very deep and arbitrary nested dictionary.

d = {
    "aaa":{
        "bbb":"xyz",
        "ccc":{
            "description":"xyz",
            "data":"abc"
        },
        "description":"xyz"
    },
    "xxx":{
        "description":"xyz",
        "bbb":{
            "ccc":{
                "ddd":{
                    "description":"xyz"
                },
                "aaa":{
                    "description":{
                        "hhh": "xyz"
                    }
                },
                "zzz":{
                    "description":"xyz"
                }
            }
        }
    },
    "lll":{
        "description":"xyz",
        "bbb":{
            "ccc":{
                "hhh":{
                    "description":"xyz"
                },
                "ooo":{
                    "description":"xyz",
                    "aaa":{
                        "ddd":{
                            "description":"xyz"
                        }
                    },
                    "zzz":{
                        "ddd":{
                            "description":"xyz"
                        }
                    }
                },
                "zzz":{
                    "description":"xyz"
                }
            }
        }
    }
} 

Now I want to search all levels of the dictionary and check if the keys "aaa" & "zzz" occur in this level. If this is the case, I want to output the keys with the respective values in a list with tuples.

[('aaa:  {'ddd':{'description':'xyz'}', 'zzz:  {'description':'xyz'}'),
('aaa:{'ddd':{'description':'xyz'}}', 'zzz:{'description':'xyz'})
]

I know that with

d.keys() 

can print all keys in one layer.

I know that with this function I can go through all keys and values in the dictionary

def recursive_items(dictionary):
    for key, value in dictionary.items():
        if type(value) is dict:
            yield from recursive_items(value)
        else:
            yield (key, value)

However, I am having trouble linking the two and putting the output into a list of tuples.

CodePudding user response:

Try (d is dictionary from your question):

def find(d, keys=("aaa", "zzz")):
    if isinstance(d, dict):
        if all(k in d for k in keys):
            yield tuple((k, d[k]) for k in keys)
        for v in d.values():
            yield from find(v, keys)
    elif isinstance(d, list):
        for v in d:
            yield from find(v, keys)


print(list(find(d)))

Prints:

[
    (
        ("aaa", {"description": {"hhh": "xyz"}}), 
        ("zzz", {"description": "xyz"})),
    (
        ("aaa", {"ddd": {"description": "xyz"}}),
        ("zzz", {"ddd": {"description": "xyz"}}),
    ),
]

  • Related