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"}}),
),
]