Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python: find all keys with a value

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?

like image 848
nad Avatar asked Dec 14 '22 18:12

nad


2 Answers

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']
like image 146
Mazdak Avatar answered Dec 18 '22 00:12

Mazdak


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']
like image 23
juanpa.arrivillaga Avatar answered Dec 18 '22 00:12

juanpa.arrivillaga