Why does "[] == False" evaluate to False when "if not []" succeeds?
I'm asking this because I know that the pythonic way to check whether a list is empty or not is the following:
my_list = []
if not my_list:
print "computer says no"
else:
# my_list isn't empty
print "computer says yes"
will print computer says no
, etc. So this leads me to identify []
with False
truth-values; however, if I try to compare [] and False "directly", I obtain the following:
>>> my_list == False
False
>>> my_list is False
False
>>> [] == False
False
etc...
What's going on here? I feel like I'm missing something really obvious.
Solution 1:
The if
statement evaluates everything in a Boolean context, it is like there is an implicit call to the bool()
built-in function.
Here is how you would actually check how things will be evaluated by an if
statement:
>>> bool([])
False
>>> bool([]) == False
True
See the documentation on Truth Value Testing, empty lists are considered false, but this doesn't mean they are equivalent to False
.
PEP 285 also has some excellent information on why it was implemented this way, see the very last bullet in the Resolved Issues section for the part that deals with x == True
and x == False
specifically.
The most convincing aspect to me is that ==
is generally transitive, so a == b
and b == c
implies a == c
. So if it were the way you expected and [] == False
were true and '' == False
were true, one might assume that [] == ''
should be true (even though it obviously should not be in a language without implicit type conversion).
Solution 2:
Empty containers are "falsy," that is, they evaluate to False
in a Boolean context. That doesn't mean they are literally equal to the constant False
.
In other words, the following is True
:
bool([]) == False
The truth value of an object is determined by its __nonzero__()
or its __len__()
method. (In Python 3, __nonzero__()
has been renamed to __bool__()
.) Containers have a __len__()
method, so they are truthy when they have anything in them and falsy when they are empty.
If empty containers were literally equal to False
, by the way, then any empty container would be equal to any other empty container: for example, {} == ""
would be True
. And that just wouldn't make any sense at all!
However, just to blow your mind, the following is True
:
False == 0
This is because Booleans are a subclass of integers in Python, and False
is basically just a zero that gets printed a little differently.
Solution 3:
Built-in types in Python have a truth value which allows you to test them for truthfulness. See Truth Value Testing.
This is different than saying object == False
which is doing an actual value test (equality test). It is using the objects __eq__()
method to determine if their values are equal.