2012-05-03 2 views
26

Я спрашиваю об этом, потому что я знаю, что вещий способ проверить, является ли список пуст или не является следующее:Почему «[] == 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 истины -значения; Однако, если я пытаюсь сравнить [] и Ложное «непосредственно», я получаю следующее:

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

и т.д ...

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

+4

Это отличный дизайн, так как он также позволяет программистам не использовать опцию 'if variable == True:'. Это должно быть либо 'if variable is True:' (Это точно True, а не что-то еще - не лучший способ делать что-то в большинстве случаев), или 'if variable' (это правда-y). – Darthfett

ответ

49

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

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

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

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

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

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

+18

«Даже если это явно не должно быть», *** Javascript ***. –

13

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

Другими словами, следующее True:

bool([]) == False 

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

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

Однако, просто взорвать ваш разум, следующий True:

False == 0 

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

7

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

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

+0

Я нахожу этот самый полезный ответ лично. Истина является интересной концепцией и может привести к некоторым неинтуитивным последствиям. В качестве примера возьмем JavaScript и его нижние значения. – dwerner

+1

@ dwerner: Да, я согласен. Я просто пытаюсь думать об этом как «если этот объект имеет контент», когда я говорю 'if object:' – jdi

3

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

>>> not [] 
True 

>>> not [1] 
False 

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

+3

Это действительно хороший момент, когда оператор 'not' преобразуется в логическое, но у вас есть обратное. '(not []) == True' и' (not [1]) == False'. –

+0

Спасибо. Я исправлю это. –

Смежные вопросы