Ответ 1
Чтобы проверить, находится ли элемент в списке, сначала тестирует Python для идентификации объекта, а затем проверяет равенство только в том случае, если объекты разные. 1
float("NaN") in [float("NaN")]
False, потому что в сравнении участвуют два разных объекта NaN
. Поэтому тест на идентификацию возвращает False, а затем тест равенства также возвращает False, поскольку NaN != NaN
.
np.nan in [np.nan, 1, 2]
, однако, является Истинным, потому что тот же объект NaN
участвует в сравнении. Тест на идентификацию объекта возвращает True, и поэтому Python немедленно распознает элемент как находящийся в списке.
Метод __contains__
(вызванный с помощью in
) для многих других типов контейнеров Python, таких как кортежи и наборы, реализуется с использованием той же проверки.
1 По крайней мере, это верно в CPython. Идентификация объекта здесь означает, что объекты находятся по одному и тому же адресу памяти: содержит метод для списков, выполняется с помощью PyObject_RichCompareBool
, который быстро сравнивает указатели объектов перед потенциально более сложным сопоставлением объектов. Другие реализации Python могут отличаться.