Подтвердить что ты не робот

Почему в numpy `nan == nan` является False, а nan in [nan] является True?

В то время как первая часть вопроса (которая находится в заголовке) ответила несколько раз раньше (т.е. Почему NaN не соответствует NaN?), Я не понимаю, почему вторая часть работает так, как она делает (вдохновленная этим вопросом Как проверить список, содержащий NaN)?

А именно:

>> nan == nan
False

>> nan in [nan]
True

Пояснительное дополнение к вопросу, рассматривающему ответ от @DSM. Итак, почему float("nan") ведет себя иначе, чем nan? Разве он не должен снова оцениваться простым nan и почему интерпретатор ведет себя таким образом?

>> x = float("nan")
>> y = nan
>> x
nan
>> y
nan
>> x is nan, x is float("nan"), y is nan
(False, False, True)

В принципе, он относится к тому же родовому nan в первом случае, но создает отдельный объект во втором:

>> 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]
4b9b3361

Ответ 1

nan, не равный nan, является частью определения nan, поэтому эта часть легко.

Что касается nan in [nan] как True, это потому, что идентификация проверяется перед равенством для сдерживания в списках. Вы сравниваете те же два объекта.

Если вы попытались сделать то же самое с двумя разными nan s, вы получите 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

Ваше приложение не имеет особого отношения к nan, это просто то, как работает Python. Как только вы поймете, что float("nan") не обязана возвращать какой-либо одноандерный nan, а y = x не делает копию x, а вместо этого связывает имя y с объектом, названным x, там ничего не осталось.