Reputation: 839
In the book Mastering Object-Oriented Python, it says
There are three tiers of equality comparison:
• Same Hash Value: This means that two objects could be equal. The hash value provides us with a quick check for likely equality. If the hash value is different, the two objects cannot possibly be equal, nor can they be the same object.
• Compare As Equal: This means that the hash values must also have been equal. This is the definition of the == operator. The objects may be the same object.
• Same IDD: This means that they are the same object. They also compare as equal and will have the same hash value. This is the definition of the is operator.
I can understand the second and third, but I really don't understand the first. Is the first and second the same. Can anybody shed some light on this? Thanks!
Upvotes: 2
Views: 209
Reputation: 18940
Consider this class:
class Foo:
def __init__(self, x):
self.x = x
def __hash__(self):
return self.x**2
def __eq__(self, o):
return o.x == self.x
(it's a class with a (numeric) attribute x
, whose hash is x^2
, and is considered equal to another object if they have the same value of the x
attribute)
Now create 5 variables of type Foo
:
>>> a=Foo(1)
>>> b=Foo(1)
>>> c=Foo(-1)
>>> d=Foo(2)
>>> e=a
a
and b
have the same hashcode, and are equal, but not the same object:
>>> hash(a) == hash(b)
True
>>> a == b
True
>>> a is b
False
a
and c
, despite having the same hash code, are not equal (and of course are not the same object)
>>> hash(a) == hash(c)
True
>>> a == c
False
It's obvious to say that a
and d
have divverent hash code, so they are not equal and not the same object.
a
and e
are the same object:
>>> a is e
True
consequently they are equal (and of course have the same hash code):
>>> a == e
True
It's a chain of implications:
same object ==> equal
equal ==> same hash code
Note the direction of the implication arrow: we cannot say anything for the inverse direction, i.e. if two objects have the same hash code, we don't know if they are equal (must use ==
to tell); or if two objects are equal we don't know if they are actually the same object (must use is
to tell).
Upvotes: 2
Reputation: 1126
First, hashing functions for languages are really good and usually two objects that aren't equal won't have the same hash value, but it can happen. We can demonstrate this with a bad hash function.
def hash(string):
return len(string)
This is a valid hash function, but as you can see, there will be many instances where non-equal values will return the same hash value. But like I said, the built-in hash function for python is much better and this will rarely happen, but it is possible.
Upvotes: 1