El problema aquí es que NaN no es igual a sí mismo, como se define en el estándar IEEE para números de punto flotante:
>>> float("nan") == float("nan")
False
Cuando una diccionario busca una clave, hace más o menos esto:
Calcule el hash de la clave que se va a buscar.
Para cada tecla en el dict con el mismo hash, verifique si coincide con la clave que se va a buscar. Esta comprobación se compone de
a. Comprobación de la identidad del objeto: si la clave del diccionario y la clave que se va a buscar son el mismo objeto que indica el operador is
, se encontró la clave.
b. Si falló la primera comprobación, verifique la igualdad utilizando el operador __eq__
.
El primer ejemplo tiene éxito, ya que np.nan
y np.nan
son el mismo objeto, por lo que no importa que no se comparan iguales:
>>> numpy.nan is numpy.nan
True
En el segundo caso, np.float64(np.nan)
np.float64(np.nan)
y no son el mismo objeto - las dos llamadas a constructores crean dos objetos distintos:
>>> numpy.float64(numpy.nan) is numpy.float64(numpy.nan)
False
Dado que los objetos también lo hacen no se compara igual, el diccionario concluye que la clave no se encuentra y arroja un KeyError
.
Incluso puede hacer esto:
>>> a = float("nan")
>>> b = float("nan")
>>> {a: 1, b: 2}
{nan: 1, nan: 2}
En conclusión, parece una idea más sano para evitar NaN como una clave de diccionario.
esto siempre será cierto: 'float ('nan')! = Float ('nan')' – JBernardo