Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #197793 > unrolled thread
| Started by | Veek M <veekjunk@foobar.com> |
|---|---|
| First post | 2026-05-31 08:28 +0000 |
| Last post | 2026-05-31 13:06 +0000 |
| Articles | 5 — 4 participants |
Back to article view | Back to comp.lang.python
Python __hash__ return value - what use is it? Veek M <veekjunk@foobar.com> - 2026-05-31 08:28 +0000
Re: Python __hash__ return value - what use is it? Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-05-31 09:25 +0000
Re: Python __hash__ return value - what use is it? Veek M <veekjunk@foobar.com> - 2026-05-31 10:13 +0000
Re: Python __hash__ return value - what use is it? ram@zedat.fu-berlin.de (Stefan Ram) - 2026-05-31 09:40 +0000
Re: Python __hash__ return value - what use is it? Jon Ribbens <jon+usenet@unequivocal.eu> - 2026-05-31 13:06 +0000
| From | Veek M <veekjunk@foobar.com> |
|---|---|
| Date | 2026-05-31 08:28 +0000 |
| Subject | Python __hash__ return value - what use is it? |
| Message-ID | <10vgrfu$1dchl$1@dont-email.me> |
1. So I am returning 1 for every instance of MyClass and then inserting
the instances into a set. However when I print the set I see individual
instances though I want the instances to be the treated the same .ie there
should be just one instance in the set because the return value from
__hash__ is always 1.
In the dictionary when I print it I see the instances as individual keys
though I want to see a single key - what gives?? Why is the return value
of __hash__ being ignored?? (I can see it's being called)
2. When is __eq__ used? If I have two instances and want to make them
equal - what's the use case?
#!/usr/bin/python
class MyClass:
def __bool__(self):
print('in __bool__')
return True
def __hash__(self):
# hash value is not a key
print('in __hash__')
return 1
def __eq__(self, val):
print('in __eq__', val)
return True
c = MyClass()
d = MyClass()
if c:
print("true")
print('-----')
s = set()
s.add(c)
s.add(d)
print(s)
print('-----')
d = { c : "10", d : "20" }
print(d)
[toc] | [next] | [standalone]
| From | Lawrence D’Oliveiro <ldo@nz.invalid> |
|---|---|
| Date | 2026-05-31 09:25 +0000 |
| Message-ID | <10vguqb$1ecdn$1@dont-email.me> |
| In reply to | #197793 |
On Sun, 31 May 2026 08:28:46 -0000 (UTC), Veek M wrote:
> However when I print the set I see individual instances though I
> want the instances to be the treated the same .ie there should be
> just one instance in the set because the return value from __hash__
> is always 1.
>
> In the dictionary when I print it I see the instances as individual
> keys though I want to see a single key - what gives??
Just tried your code in a Jupyter notebook under Python 3.13.12, and
this was the output:
in __bool__
true
-----
in __hash__
in __hash__
in __eq__ <__main__.MyClass object at 0x7f68a86a4410>
{<__main__.MyClass object at 0x7f68a8691400>}
-----
in __hash__
in __hash__
in __eq__ <__main__.MyClass object at 0x7f68a86a4410>
{<__main__.MyClass object at 0x7f68a8691400>: '20'}
As you expected, only a single element in the set, and only a single
entry in the dict.
[toc] | [prev] | [next] | [standalone]
| From | Veek M <veekjunk@foobar.com> |
|---|---|
| Date | 2026-05-31 10:13 +0000 |
| Message-ID | <10vh1kq$1f26j$1@dont-email.me> |
| In reply to | #197794 |
On Sun, 31 May 2026 09:25:32 -0000 (UTC), Lawrence D’Oliveiro wrote:
> On Sun, 31 May 2026 08:28:46 -0000 (UTC), Veek M wrote:
>
>> However when I print the set I see individual instances though I want
>> the instances to be the treated the same .ie there should be just one
>> instance in the set because the return value from __hash__
>> is always 1.
>>
>> In the dictionary when I print it I see the instances as individual
>> keys though I want to see a single key - what gives??
>
> Just tried your code in a Jupyter notebook under Python 3.13.12, and
> this was the output:
>
> in __bool__
> true -----
> in __hash__
> in __hash__
> in __eq__ <__main__.MyClass object at 0x7f68a86a4410>
> {<__main__.MyClass object at 0x7f68a8691400>}
> -----
> in __hash__
> in __hash__
> in __eq__ <__main__.MyClass object at 0x7f68a86a4410>
> {<__main__.MyClass object at 0x7f68a8691400>: '20'}
>
> As you expected, only a single element in the set, and only a single
> entry in the dict.
Oh. hmm - sorry - I guess I misread the output - I was under the
impression there were two instances. Should have used len to check though.
[toc] | [prev] | [next] | [standalone]
| From | ram@zedat.fu-berlin.de (Stefan Ram) |
|---|---|
| Date | 2026-05-31 09:40 +0000 |
| Message-ID | <hash-20260531103449@ram.dialup.fu-berlin.de> |
| In reply to | #197793 |
Veek M <veekjunk@foobar.com> wrote or quoted:
>the instances into a set. However when I print the set I see individual
>instances though I want the instances to be the treated the same .ie there
>should be just one instance in the set because the return value from
>__hash__ is always 1.
I used the code below, where I added statements to print lengths,
and all lengths printed are always "1" for me.
Python Code
#!/usr/bin/python
class MyClass:
def __bool__(self):
print('in __bool__')
return True
def __hash__(self):
# hash value is not a key
print('in __hash__')
return 1
def __eq__(self, val):
print('in __eq__', val)
return True
c = MyClass()
d = MyClass()
if c:
print("true")
print('-----')
s = set()
s.add(c); print( "len( s )= ", len( s ))
s.add(d); print( "len( s )= ", len( s ))
print(s)
print('-----')
d = { c : "10", d : "20" }
print( "len( d )= ", len( d ))
print(d)
Python Output (abbreviated at "...")
in __bool__
true
-----
in __hash__
len( s )= 1
in __hash__
in __eq__ <__main__.MyClass object at ...>
len( s )= 1
{<__main__.MyClass object at ...>}
-----
in __hash__
in __hash__
in __eq__ <__main__.MyClass object at ...>
len( d )= 1
{<__main__.MyClass object at ...>: '20'}
[toc] | [prev] | [next] | [standalone]
| From | Jon Ribbens <jon+usenet@unequivocal.eu> |
|---|---|
| Date | 2026-05-31 13:06 +0000 |
| Message-ID | <slrn111ocj0.4cm2.jon+usenet@raven.unequivocal.eu> |
| In reply to | #197793 |
On 2026-05-31, Veek M <veekjunk@foobar.com> wrote: > 1. So I am returning 1 for every instance of MyClass and then inserting > the instances into a set. However when I print the set I see individual > instances though I want the instances to be the treated the same .ie there > should be just one instance in the set because the return value from > __hash__ is always 1. That doesn't follow. As others have already said, you do indeed have only one item in the set. But that's not becuase __hash__ is returning the same value every time - or at least, not only because of that. If __eq__ was not returning True, then you would get 2 items in the set, regardless of what __hash__ was returning. If two items are "equal" then their hashes must be the same. If they are not equal then their hashes do not need to be different. The hash is just for efficiency. Imagine you had a set of 1MB strings - you wouldn't want to have to compare each 1MB string with every other 1MB string when deciding whether a new string is different or not. So you compare the hashes, and then only if the hashes are the same do you compare the strings themselves. In short: if you make a class which returns the same __hash__ for every object, you won't change its behaviour, you will just make it (much) slower when used in things like sets and dictionaries. > 2. When is __eq__ used? If I have two instances and want to make them > equal - what's the use case? So "x == y" returns the result you want it to?
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web