Назначение переменной NaN в python без numpy

В большинстве языков есть константа NaN, которую вы можете использовать для назначения переменной значение NaN. Может ли python делать это без использования numpy?

Ответ 1

Да - используйте float('nan'). С Python 3.5 вы также можете использовать math.nan.

>>> a = float('nan')
>>> print(a)
nan
>>> print(a + 2)
nan
>>> a == a
False
>>> import math
>>> math.isnan(a)
True
>>> # Python 3.5+
>>> math.isnan(math.nan)
True

Функция float(...) нечувствительна к регистру - выполнение float('nan') или float('nan') или аналогичные вещи также будут работать.

Обратите внимание, что проверка того, что две вещи, которые являются NaN равны друг другу, всегда вернет false. Частично это объясняется тем, что две вещи, которые "не являются числом", не могут (строго говоря) быть равными друг другу - см. В чем обоснование всех сравнений, возвращающих false для IEEE754 NaN значения? для получения более подробной информации и информации.

Вместо этого используйте math.isnan(...), если вам нужно определить, является ли значение NaN или нет.

Кроме того, точная семантика операции == по значению NaN может вызвать незначительные проблемы при попытке сохранить NaN внутри типов контейнеров, таких как list или dict (или при использовании пользовательских типов контейнеров). Подробнее см. Проверка наличия NaN в контейнере.


Вы также можете построить числа NaN, используя модуль Python decimal:

>>> from decimal import Decimal
>>> b = Decimal('nan')
>>> print(b)
NaN
>>> print(repr(b))
Decimal('NaN')
>>>
>>> Decimal(float('nan'))
Decimal('NaN')
>>> 
>>> import math
>>> math.isnan(b)
True

math.isnan(...) также будет работать с десятичными объектами.


Однако вы не можете построить числа NaN в Python fractions module:

>>> from fractions import Fraction
>>> Fraction('nan')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python35\lib\fractions.py", line 146, in __new__
    numerator)
ValueError: Invalid literal for Fraction: 'nan'
>>>
>>> Fraction(float('nan'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python35\lib\fractions.py", line 130, in __new__
    value = Fraction.from_float(numerator)
  File "C:\Python35\lib\fractions.py", line 214, in from_float
    raise ValueError("Cannot convert %r to %s." % (f, cls.__name__))
ValueError: Cannot convert nan to Fraction.

Кстати, вы также можете сделать float('Inf'), Decimal('Inf') или math.inf (3.5+), чтобы назначить бесконечные числа. (И также см. math.isinf(...))

Однако выполнение Fraction('Inf') или Fraction(float('inf')) недопустимо и генерирует исключение, как NaN.

Если вам нужен быстрый и простой способ проверить, не является ли число ни NaN, ни бесконечным, вы можете использовать math.isfinite(...) с Python 3.2 +.


Если вы хотите выполнять аналогичные проверки с комплексными числами, модуль cmath содержит аналогичный набор функций и констант в качестве модуля math:

Ответ 2

nan = float('nan')

И теперь у вас есть константа, nan.

Аналогичным образом вы можете создавать значения NaN для decimal.Decimal.:

dnan = Decimal('nan')

Ответ 3

Используйте float("nan"):

>>> float("nan")
nan

Ответ 4

Вы можете сделать float('nan'), чтобы получить NaN.

Ответ 5

Более последовательный (и менее непрозрачный) способ генерации inf и -inf - это снова использовать float():

>> positive_inf = float('inf')
>> positive_inf
inf
>> negative_inf = float('-inf')
>> negative_inf
-inf

Обратите внимание, что размер поплавка изменяется в зависимости от архитектуры, поэтому лучше избегать использования магических чисел, таких как 9e999, даже если это может сработать.

import sys
sys.float_info
sys.float_info(max=1.7976931348623157e+308,
               max_exp=1024, max_10_exp=308,
               min=2.2250738585072014e-308, min_exp=-1021,
               min_10_exp=-307, dig=15, mant_dig=53,
               epsilon=2.220446049250313e-16, radix=2, rounds=1)

Ответ 6

Вы можете получить NaN из "inf-inf", и вы можете получить "inf" с номера больше 2e308, поэтому я обычно использовал:

>>> inf = 9e999
>>> inf
inf
>>> inf - inf
nan