NaN is handled perfectly when I check for its presence in a list or a set. But I don\'t understand how. [UPDATE: no it\'s not; it is reported as present if the identical ins
I can't repro you tuple/set cases using float('nan')
instead of NaN
.
So i assume that it worked only because id(NaN) == id(NaN)
, i.e. there is no interning for NaN
objects:
>>> NaN = float('NaN')
>>> id(NaN)
34373956456
>>> id(float('NaN'))
34373956480
And
>>> NaN is NaN
True
>>> NaN is float('NaN')
False
I believe tuple/set lookups has some optimization related to comparison of the same objects.
Answering your question - it seam to be unsafe to relay on in
operator while checking for presence of NaN
. I'd recommend to use None
, if possible.
Just a comment. __eq__
has nothing to do with is
statement, and during lookups comparison of objects' ids seem to happen prior to any value comparisons:
>>> class A(object):
... def __eq__(*args):
... print '__eq__'
...
>>> A() == A()
__eq__ # as expected
>>> A() is A()
False # `is` checks only ids
>>> A() in [A()]
__eq__ # as expected
False
>>> a = A()
>>> a in [a]
True # surprise!