Why do Sets allow multiple of the same object with changing hashCodes?

Viewed 178

According to my understanding, sets can only have one of each object in them. But I have found the following example where a set has two of the same object

class myObject:

    def __init__(self, x):
        self.x = x

    def set(self, x):
        self.x = x

    def __hash__(self):
        return self.x

    def __eq__(self, o):
        return self.x == o.x

    def __str__(self):
        return str(self.x)

    def __repr__(self):
        return str(self.x)

When I run the following:

x = myObject(1)

mySet = {x}

x.set(2)
mySet.add(x)

print(mySet)

x.set(3)

print(mySet)

I get the following output:

{2, 2}
{3, 3}

If I remove the __str__ and __repr__ methods it shows there are two objects in the set with the same memory address:

{<__main__.myObject object at 0x10e3a10d0>, <__main__.myObject object at 0x10e3a10d0>}

I am aware python doesn't allow things like lists to be hashed because the hashcode can change causing a similar error to what is shown above. Why is python allowing this but not for things like lists etc. Surely Python should also have some way of managing changing hashes.

I have tested this same example on java and the same thing happens. Why do these languages allow this?

1 Answers

had a link in here to the docs, which address the hash

What is a hash: https://docs.python.org/3/reference/datamodel.html#object.hash

What is hashable (IMPORTANT): https://docs.python.org/3/glossary.html#term-hashable

"An object is hashable if it has a hash value which never changes during its lifetime..."

Looking at the set object itself after you have modified x.

s = set()
x = myObject(2)

Then look at the set member's hash:

enter image description here

Then:

x.set(4)

enter image description here

No change. In fact, if you continue to use that set in other places (e.g. fs = frozenset(s)) you will continue to pass around the old hash.

Related