Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding key from value in Python dictionary:

Fairly new to Python, still struggling with so much information.

All the documentation I've seen about dictionaries explain various ways of getting a value via a key - but I'm looking for a pythonic way to do the opposite - get a key via a value.

I know I can loop through the keys and inspect their values until I find the value I'm looking for and then grab the key, but I'm looking for a direct route.

like image 237
Vector Avatar asked Oct 05 '11 06:10

Vector


People also ask

Can you get key from value in dictionary python?

We can also fetch the key from a value by matching all the values using the dict. item() and then print the corresponding key to the given value.

How do you separate a key from a value in a dictionary?

Creating a Dictionary To do that you separate the key-value pairs by a colon(“:”). The keys would need to be of an immutable type, i.e., data-types for which the keys cannot be changed at runtime such as int, string, tuple, etc. The values can be of any type.

How do I find a key in a dictionary?

Using has_key() method returns true if a given key is available in the dictionary, otherwise, it returns a false. With the Inbuilt method has_key(), use the if statement to check if the key is present in the dictionary or not.

How do I search for a key in Python?

To simply check if a key exists in a Python dictionary you can use the in operator to search through the dictionary keys like this: pets = {'cats': 1, 'dogs': 2, 'fish': 3} if 'dogs' in pets: print('Dogs found!') # Dogs found! A dictionary can be a convenient data structure for counting the occurrence of items.


1 Answers

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.

like image 200
Chris Morgan Avatar answered Oct 12 '22 13:10

Chris Morgan