Bi Directional Dictionary I wrote a class that extends the dict class to provide indexing like functionality, so I can find which key(s) map to a given value in the dict. It's pretty bare bones and there are a lot of things I haven't fleshed out like docstrings (will add these later when I have a final version), how to handle unhashable elements (it currently just fails, but this might be changed in the future), etc.  

The extremely bare bones nature of this is because this is something I whipped up in a few minutes for immediate use.  

from collections import defaultdict  # The class currently doesn't exist in a separate module, and there are many other imports used by surrounding code.

# Do something


class DoubleDict(dict):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.values_dict = defaultdict(lambda: [])
        for key, value in self.items():
            self.values_dict[value] += [key]

    def __setitem__(self, key, value):
        var = self.get(key)
        if var in self.values_dict:
            self.values_dict[var].remove(key)
            if not self.values_dict[var]:
                del self.values_dict[var]
        super().__setitem__(key, value)
        self.values_dict[value] += [key]

    def index(self, value):
        return self.values_dict[value][-1]

    def indices(self, value):
        return self.values_dict[value]


# Do Something



My concerns are to have this be as performant as feasible, and sane and generally correct (there may be some unavoidable tradeoffs) approach. I would probably make this into its own module after incorporating feedback.
A couple of minor notes:

1) Add proper typing so that users of your code will be able to type-check their own code correctly.  I think this would look like:

from typing import Dict, List, TypeVar

_KT = TypeVar('_KT')
_VT = TypeVar('_VT')

class DoubleDict(Dict[_KT, _VT]):
    super().__init__(*args, **kwargs)
    self.values_dict: Dict[_VT, List[_KT]] = defaultdict(lambda: [])
    for key, value in self.items():
        self.values_dict[value] += [key]

... etc


2) I'd eliminate the index syntactic sugar, personally, because it makes it easier for the caller to forget that this isn't a one-to-one mapping in both directions.  Make them get the list and check to make sure that it's got the length they expect.

Alternatively, if you'd want it to be a one-to-one mapping in most cases, then enforce that in the setter and make it part of the class's contract.