web-dev-qa-db-fra.com

Pourquoi en numpy `nan == nan` est False alors que nan en [nan] est True?

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]
37
sashkello

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érentnans, 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.

39
DSM