0

I want to make a simple wrapper to the standard python dictionary, or maybe the defaultdict class where there is a default value.

The change I want to make is very simple: I would like to store in the dictionary data-structures that are not hashable due to the possibility of mutation, but I have guarantee in my code that I won't ever mutate them anyways.

My approach is detect if the key to the dictionary is hashable, if so proceed as usual. However if the key is not hashable, turn it into a string first then proceed as usual.

martineau
  • 119,623
  • 25
  • 170
  • 301
Evan Pu
  • 2,099
  • 5
  • 21
  • 36
  • If you're using a custom data structure, you can implement the `__hash__` method as well, which will make it hashable. – Right leg Jun 08 '17 at 15:03
  • @Rightleg I am trying to store numpy array, I think in this case the dictionary is more "custom" than the array but yeah I see your point. – Evan Pu Jun 08 '17 at 19:00

1 Answers1

2

You can inherit from dict and override __setitem__ method:

class CustomDict(dict):
    def __setitem__(self, key, value):
        try:
            hash(key)
        except TypeError:
            key = str(key)

        super(CustomDict, self).__setitem__(key, value)

    def __getitem__(self, key):
        try:
            hash(key)
        except TypeError:
            key = str(key)

        return super(CustomDict, self).__getitem__(key)

data = CustomDict()

data["x"] = True
data[dict(foo='bar')] = False
print(data)
>>> {'x': True, "{'foo': 'bar'}": False}
assert data[dict(foo='bar')] == False

Or you can create custom dict-like object as described here.

grundic
  • 4,641
  • 3
  • 31
  • 47
  • @martineau, I've updated my answer. It's not going to be bulletproof, though -- otherwise python would be able to do that on it's own. – grundic Jun 08 '17 at 15:51