33 votes

dans l'opérateur, le type float("NaN") et np.nan

Je croyais que l' in opérateur en Python vérifie la présence de l'élément dans un ensemble à l'aide de l'égalité vérification de l' ==, alors element in some_list est à peu près équivalent à any(x == element for x in some_list). Par exemple:

True in [1, 2, 3]
# True because True == 1

ou

1 in [1., 2., 3.]
# also True because 1 == 1.

Cependant, il est bien connu que l' NaN n'est pas égal à lui-même. J'ai donc attendu qu' float("NaN") in [float("NaN")] est False. Et il est False en effet.

Cependant, si nous utilisons numpy.nan au lieu de float("NaN"), la situation est très différente:

import numpy as np
np.nan in [np.nan, 1, 2]
# True

Mais np.nan == np.nan donne encore False!

Comment est-il possible? Quelle est la différence entre np.nan et float("NaN")? Comment est - in traitent np.nan?

32voto

ajcr Points 4047

Pour vérifier si l'élément est dans la liste, Python tests pour l'identité de l'objet premier, puis les tests pour l'égalité seulement si les objets sont différents.1

float("NaN") in [float("NaN")] est Faux car deux différents NaN des objets sont impliqués dans la comparaison. Le test d'identité donc retourne False, et puis le test d'égalité renvoie également Faux, puisque NaN != NaN.

np.nan in [np.nan, 1, 2] est cependant Vrai, parce que le même NaN objet est impliqué dans la comparaison. Le test de l'identité de l'objet renvoie la valeur True et ainsi de Python reconnaît aussitôt l'élément comme étant dans la liste.

L' __contains__ méthode (appelée à l'aide de in) pour beaucoup de Python d'autres builtin types de récipients, tels que des tuples et des ensembles, est mis en œuvre à l'aide de la même vérification.


1 Au moins cela est vrai dans Disponible. L'identité de l'objet, ici, signifie que les objets qui se trouvent à la même adresse mémoire: la méthode contains pour les listes est effectuée à l'aide de PyObject_RichCompareBool qui s'est rapidement compare les pointeurs d'objet avant de potentiellement plus compliqué objet de comparaison. D'autres implémentations de Python peuvent différer.

6voto

Paul Panzer Points 30707

Une chose à noter est que les tableaux numpy faire se comporter comme prévu:

a = np.array((np.nan,))
a[0] in a
# False

Les Variations du thème:

[np.nan]==[np.nan]
# True
[float('nan')]==[float('nan')]
# False
{np.nan: 0}[np.nan]
# 0
{float('nan'): 0}[float('nan')]
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# KeyError: nan

Tout le reste est couvert dans @AlexRiley excellente réponse.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X