Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Classes as dictionary keys in Python

So, I’ve done a lot of research on this and saw various other links and conferred with the Python documentation, however, I’m still a bit unclear on this.

Maybe the way I see classes in Python is a bit wrong.

As I understand, keys in a dictionary must be immutable. However, classes can be keys in a dictionary because of their default hash implementation (I think?). Why is this the case since classes are mutable?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

For example,

class C:
    def __init__(self):
        self.val = 15
        self.array = []

c = C()

D = {c: 15}
c.val = 14
c.array.append(15)

print(D[c])

Why is this okay?

>Solution :

Instances of your C class are actually hashable, it comes with a default implementation of __hash__ which pertains to the identity of that object:

>>> hash(c) # calls c.__hash__()
306169194

This __hash__ implementation allows your instance to be used as a key in a dictionary.

This explains "Why doesn’t changing things in your class change the hash?" — because the identity/reference of the instance doesn’t change even if its contents do.

On older versions of python, this used to be exactly equal to the object’s id, but from python 3 onwards, it seems to be some derivative of it. This post goes into the gory details on the hash implementation.


Now let’s say you wanted to prevent instances of your class from being used as a key… you could then do this:

class C:
    def __init__(self):
        self.val = 15
        self.array = []

    def __hash__(self):
        pass # overriding __hash__ to return None

c = C()

And now you get

>>> {c: 15}
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-521-e2ccd28b0d8f> in <module>
----> 1 {c: 15}

TypeError: __hash__ method should return an integer
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading