NaN comparisons - Call For Anecdotes
Chris Angelico
rosuav at gmail.com
Tue Jul 8 13:54:52 EDT 2014
On Wed, Jul 9, 2014 at 3:31 AM, Marko Rauhamaa <marko at pacujo.net> wrote:
> Chris Angelico <rosuav at gmail.com>:
>
>> I'd say it would surprise people rather a lot if operations like dict
>> insertion/lookup could trigger arithmetic exceptions. :)
>
> That wouldn't trigger exceptions.
>
> Dict operations do an "is" test before an "==" test. In fact, you
> couldn't even use NaN as a dict key otherwise. Thus, dict operations
> never test NaN == NaN.
Check out the example I posted early in this thread of a dict with
three keys, all of them NaN. And note that hash(float("nan"))==0. Now
try looking up d[0]. Before it raises KeyError, it has to compare that
0 for equality with each of the nans, because it can't shortcut it
based on the hash. In fact, I can prove it thus:
>>> class X:
def __eq__(self, other):
if self is other:
print("Comparing against self - I am me!")
return True
print("Comparing against",other,"-",id(other))
return False
def __hash__(self):
return 0
>>> d[X()]
Comparing against nan - 18777952
Comparing against nan - 19624864
Comparing against nan - 18776272
Traceback (most recent call last):
File "<pyshell#20>", line 1, in <module>
d[X()]
KeyError: <__main__.X object at 0x016B40D0>
Any lookup of anything with a hash of 0 will do this. 0 itself (as any
type of number), another NaN, or anything at all. For the dict to work
sanely, these comparisons have to work and be False.
ChrisA
More information about the Python-list
mailing list