Bien que la première partie de la question (qui se trouve dans le titre) ait été répondue à plusieurs reprises auparavant (c'est-à-dire pourquoi NaN n'est-il pas égal à NaN? ), je ne vois pas pourquoi la deuxième pièce fonctionne comme il le fait (inspiré par cette question Comment vérifier la liste contenant NaN )?
À savoir:
>> nan == nan
False
>> nan in [nan]
True
Un addendum explicatif à la question considérant la réponse de @DSM. Alors, pourquoi float("nan")
se comporte différemment de nan
? Ne devrait-il pas réévaluer le simple nan
et pourquoi l'interpréteur se comporte de cette façon?
>> x = float("nan")
>> y = nan
>> x
nan
>> y
nan
>> x is nan, x is float("nan"), y is nan
(False, False, True)
Fondamentalement, il fait référence au même nan
générique dans le premier cas, mais crée un objet séparé dans le 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
différent de nan
fait partie de la définition de nan
, donc cette partie est facile.
Quant à nan in [nan]
Étant vrai, c'est parce que l'identité est testée avant l'égalité pour le confinement dans les listes. Vous comparez les deux mêmes objets.
Si vous essayez la même chose avec deux différentnan
s, vous obtiendrez 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
Votre addendum n'a pas vraiment grand-chose à voir avec nan
, c'est simplement ainsi que fonctionne Python. Une fois que vous comprenez que float("nan")
n'est pas obligé de retourner certains nan singleton, et que y = x
ne fait pas une copie de x
mais lie plutôt le nom y
à l'objet nommé par x
, il n'y a rien gauche pour obtenir.