Checking for NaN presence in a container

前端 未结 2 1996
予麋鹿
予麋鹿 2020-12-16 00:42

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

2条回答
  •  时光取名叫无心
    2020-12-16 01:16

    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!
    

提交回复
热议问题