Finding key from value in Python dictionary:

There is no direct route. It's pretty easy with list comprehensions, though;

[k for k, v in d.iteritems() if v == desired_value]

If you need to do this occasionally and don't think it's worth while indexing it the other way as well, you could do something like:

class bidict(dict):
    def key_with_value(self, value, default=None):
        for k, v in self.iteritems():
            if v == value:
                return v
        return default

    def keys_with_value(self, value, default=None):
        return [v for k, v in self.iteritems() if v == value]

Then d.key_with_value would behave rather like d.get, except the other way round.

You could also make a class which indexed it both ways automatically. Key and value would both need to be hashable, then. Here are three ways it could be implemented:

  • In two separate dicts, with the exposing some dict-like methods; you could perhaps do foo.by_key[key] or foo.by_value[value]. (No code given as it's more complicated and I'm lazy and I think this is suboptimal anyway.)

  • In a different structure, so that you could do d[key] and d.inverse[value]:

    class bidict(dict):
        def __init__(self, *args, **kwargs):
            self.inverse = {}
            super(bidict, self).__init__(key, value)
    
        def __setitem__(self, key, value):
            super(bidict, self).__setitem__(key, value)
            self.inverse[value] = key
    
        def __delitem__(self, key):
            del self.inverse[self[key]]
            super(bidict, self).__delitem__(key)
    
  • In the same structure, so that you could do d[key] and d[value]:

    class bidict(dict):
        def __setitem__(self, key, value):
            super(bidict, self).__setitem__(key, value)
            super(bidict, self).__setitem__(value, key)
    
        def __delitem__(self, key):
            super(bidict, self).__delitem__(self[key])
            super(bidict, self).__delitem__(key)
    

(Notably absent from these implementations of a bidict is the update method which will be slightly more complex (but help(dict.update) will indicate what you'd need to cover). Without update, bidict({1:2}) wouldn't do what it was intended to, nor would d.update({1:2}).)

Also consider whether some other data structure would be more appropriate.


Since your dictionary can contain duplicate values (i.e. {'a': 'A', 'b': 'A'}), the only way to find a key from value is to iterate over the dictionary as you describe.

Or... build the opposite dictionary. you have to recreate it after each modification of the original dictionary.

Or... write a class that maintains both-ways dictionary. You will have to manage situations where duplicate value appears.


the first solution with the list comprehension is good. but a small fix for python 3.x, instead of .iteritems() it should be just .items():

[k for k, v in d.items() if v == desired_value]