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.