Why in numpy `nan == nan` is False while nan in [nan] is True?
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)?
>> 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]
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 nans, you'd get False:
>>> nans = [float("nan") for i in range(2)] >>> map(id, nans) [190459300, 190459284] >>> nans [nan, nan] >>> nans is nans False >>> nans in nans True >>> nans 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.