I have a dictionary like below:
mydict = {'a' : 'apple',
'b' : 'bobb',
'c' : {
'd' : 'dog'
},
'e' : 'dog'
}
Suppose I want to find all the keys with value 'dog
'In case of nesting, the keys should be separated by a dot.
So the output should be a list ['e', 'c.d']
Now if I write below code in python 3, it only outputs 'e
'.
print(list(mydict.keys())[list(mydict.values()).index('dog')])
How can I get the nested keys?
You can use a recursion function like following:
def find_key(mydict, pre=tuple()):
for key, value in mydict.items():
if isinstance(value, dict):
yield from find_key(value, pre=pre+(key,))
elif value == 'dog':
if pre:
yield '.'.join(pre + (key,))
else:
yield key
test:
In [23]: list(find_key(mydict))
Out[23]: ['e', 'c.d']
In [26]: mydict = {'a' : 'apple',
'b' : 'bobb',
'c' : {
'd' : 'dog'
},
'e' : 'dog',
'k':{'f':{'c':{'x':'dog'}}}}
In [27]:
In [27]: list(find_key(mydict))
Out[27]: ['k.f.c.x', 'e', 'c.d']
You can use recursion (although @Kasramvd beat me to it, here is a non-generator version for good measure):
>>> def find_key(value, d, level=None, acc=None):
... acc = acc if acc is not None else []
... level = level if level is not None else []
... for k,v in d.items():
... if isinstance(v, dict):
... find_key(value, v, level=[*level, k], acc=acc)
... elif v == value:
... acc.append('.'.join([*level,k]))
... return acc
...
>>>
>>> find_key('dog', mydict)
['c.d', 'e']
And with Kasramvd's messier test-case:
>>> mydict = {'a' : 'apple',
... 'b' : 'bobb',
... 'c' : {
... 'd' : 'dog'
... },
... 'e' : 'dog',
... 'k':{'f':{'c':{'x':'dog'}}}}
>>> find_key('dog', mydict)
['c.d', 'e', 'k.f.c.x']
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With