Why in numpy `nan == nan` is False while nan in [nan] is True?

nan, numpy, python

Solution

`nan` not being equal to `nan` is part of the definition of `nan`, so that part's easy.

As for `nan in [nan]` being True, that's because identity is tested before equality for containment in lists. You're comparing the same two objects.

If you tried the same thing with two different `nan`s, you'd get False:

>>> nans = [float("nan") for i in range(2)]
>>> map(id, nans)
[190459300, 190459284]
>>> nans
[nan, nan]
>>> nans[0] is nans[1]
False
>>> nans[0] in nans
True
>>> nans[0] in nans[1:]
False

Your addendum doesn't really have much to do with `nan`, that's simply how Python works. Once you understand that `float("nan")` is under no obligation to return some nan singleton, and that `y = x` doesn't make a copy of `x` but instead binds the name `y` to the object named by `x`, there's nothing left to get.

Problem

While the first part of the question (which is in the title) has been answered a few times before (i.e., Why is NaN not equal to NaN?), I don't see why the second piece works the way it does (inspired by this question How to Check list containing NaN)? Namely: ``` >> nan == nan False >> nan in [nan] True ``` An explanatory addendum to the question considering the answer from @DSM. So, why `float("nan")` is behaving differently from `nan`? Shouldn't it evaluate again to simple `nan` and why interpreter behaves this way? ``` >> x = float("nan") >> y = nan >> x nan >> y nan >> x is nan, x is float("nan"), y is nan (False, False, True) ``` Basically, it refers to same generic `nan` in the first case, but creates separate object in the second: ``` >> nans = [nan for i in range(2)] >> map(id, nans) [190459300, 190459300] >> nans = [float("nan") for i in range(2)] >> map(id, nans) [190459300, 190459301] ```

Original source

Related problems