This is how the Python boolean operators work.
From the documentation (the last paragraph explains why it is a good idea that the operators work the way they do):
In the context of Boolean operations,
and also when expressions are used by
control flow statements, the following
values are interpreted as false:
False
, None
, numeric zero of all
types, and empty strings and
containers (including strings, tuples,
lists, dictionaries, sets and
frozensets). All other values are
interpreted as true. (See the
__nonzero__()
special method for a way to change this.)
The operator not
yields True
if its
argument is false, False
otherwise.
The expression x and y
first evaluates
x
; if x
is false, its value is
returned; otherwise, y
is evaluated
and the resulting value is returned.
The expression x or y
first evaluates
x
; if x
is true, its value is
returned; otherwise, y is evaluated
and the resulting value is returned.
(Note that neither and
nor or
restrict
the value and type they return to
False
and True
, but rather return the
last evaluated argument. This is
sometimes useful, e.g., if s
is a
string that should be replaced by a
default value if it is empty, the
expression s or foo
yields the
desired value. Because not
has to
invent a value anyway, it does not
bother to return a value of the same
type as its argument, so e.g., not foo
yields False
, not
.)