varantir
varantir

Reputation: 6854

Can Keys of Dictionary be instances of a class?

Lets assume I have a class awhich has the function __eq__(self,other). Now I want to have a dictionary where the keys are instances of the class (and the values numbers, but that should not make a difference). Then I get the error:

unhashable type: 'a'

In the documenation it says that I should define __eq__ and __cmp__ in order to define __hash__, but that is not possible since my class is not comparable!!

How to solve this, folks!

edit: Ok I made it works with only a _eq_ and _hash_ method, but I am still not sure if python uses the hash method in the in operation or the _eq_ method (which should be the case I hope)

Upvotes: 2

Views: 127

Answers (4)

BartoszKP
BartoszKP

Reputation: 35891

The documentation says that beside the __hash__() it needs an __eq__() or (not "and" as you suggest) __cmp__() method.

So in your case it is enough to define the __hash__() method.

Upvotes: 3

Mp0int
Mp0int

Reputation: 18727

This is not a direct answer, but may be it can help you.

You can override __cmp__ and raise NotImplementedError to avoid usage of it.

class SomeClass():
    def __init__(self):
        pass  # your init here

    def __cmp__(self, orher):
        raise NotImplementedError('You can not compare this')

    def __eq__(self, other):
        pass  # Your eq here

    def __hash__(self):
        pass  # your hash function here 

Demo:

>> s = SomeClass()
>> s == '12'

>> NotImplementedError: You can not compare this

Upvotes: 0

Steve P.
Steve P.

Reputation: 14699

A class can be a key for a dict, so long as the hashCode for the class is constant. If at any point in time that the key, hashCode, for the class can change, then you would not be able to use it as a key.

This is precisely why a list cannot be used as a key. An alternative for the list would be to use a tuple since tuples are immutable. Again, if you can guarantee that the hashCode won't change, you're good.

Upvotes: 1

Aswin Murugesh
Aswin Murugesh

Reputation: 11070

It works for me..

>>> class A:
...     def __init__(self):
...             self.a = 5
... 
>>> a = A()
>>> d = { a:"hello"}
>>> d[a]
'hello'

You can use class instances as keys for a dict

Upvotes: 0

Related Questions