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

Почему "[] == False" оценивается в False, когда "if not []" преуспевает?

Я спрашиваю об этом, потому что я знаю, что питонический способ проверить, пуст ли пуст или нет, это следующее:

my_list = []
if not my_list:
    print "computer says no"
else:
    # my_list isn't empty
    print "computer says yes"

напечатает computer says no и т.д. Таким образом, это приводит меня к тому, чтобы идентифицировать [] с False значениями истинности; однако, если я попытаюсь сравнить [] и False "напрямую", я получаю следующее:

>>> my_list == False
False
>>> my_list is False
False
>>> [] == False
False

и т.д.

Что здесь происходит? Я чувствую, что упускаю что-то действительно очевидное.

4b9b3361

Ответ 1

Оператор if оценивает все в булевом контексте, это похоже на неявный вызов встроенной функции bool().

Вот как вы могли бы проверить, как вещи будут оцениваться оператором if:

>>> bool([])
False
>>> bool([]) == False
True

См. документацию по Проверка правдоподобия, пустые списки считаются ложными, но это не значит, что они эквивалентны False.

PEP 285 также имеет отличную информацию о том, почему он был реализован таким образом, см. последнюю брошюру в разделе "Разрешенные проблемы" для части, которая имеет дело с x == True и x == False.

Самый убедительный аспект для меня состоит в том, что == обычно транзитивен, поэтому a == b и b == c подразумевает a == c. Итак, если бы вы ожидали, и [] == False были истинными, а '' == False были истинными, можно было бы предположить, что [] == '' должен быть истинным (хотя он явно не должен быть на языке без неявного преобразования типа).

Ответ 2

Пустые контейнеры являются "ложными", то есть они оцениваются до False в булевом контексте. Это не означает, что они буквально равны константе False.

Другими словами, True:

bool([]) == False

Значение истины объекта определяется его методом __nonzero__() или его __len__(). (В Python 3, __nonzero__() было переименовано в __bool__().) Контейнеры имеют метод __len__(), поэтому они правдивы, когда в них есть что-то в них и ложные, когда они пусты.

Если пустые контейнеры были буквально равны False, кстати, любой пустой контейнер был бы равен любому другому пустующему контейнеру: например, {} == "" был бы True. И это просто не имеет никакого смысла!

Однако, просто для того, чтобы взорвать ваш разум, следующее True:

False == 0

Это связано с тем, что булевы являются подклассом целых чисел в Python, а False - это просто нуль, который печатается немного по-другому.

Ответ 3

Встроенные типы в Python имеют значение истины, которое позволяет вам проверять их на правдивость. См. Тестирование ценности правды.

Это отличается от выражения object == False, которое выполняет проверку фактического значения (тест равенства). Он использует метод __eq__() для определения того, являются ли их значения равными.

Ответ 4

В вашем примере оператор not вызывает преобразование вашего списка в логическое. Попробуйте следующее:

>>> not []
True

>>> not [1]
False

"is" и "==" не делают этого преобразования.