NaN comparisons - Call For Anecdotes

Chris Angelico rosuav at gmail.com
Tue Jul 8 19:54:52 CEST 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