Strange conversion in Python logic expressions
Nothing is being converted; the Python boolean logic operators instead short circuit.
See the boolean operators documentation:
The expression
x and y
first evaluatesx
; ifx
is false, its value is returned; otherwise,y
is evaluated and the resulting value is returned.The expression
x or y
first evaluatesx
; ifx
is true, its value is returned; otherwise,y
is evaluated and the resulting value is returned.
Moreover, numbers that are equal to 0
are considered falsey, as are empty strings and containers. Quoting from the same document:
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).
Combining these two behaviours means that for 0 and False
, the 0
is considered false and returned before evaluating the False
expression. For the expression True and 0
, True
is evaluated and found to be a true value, so 0
is returned. As far as if
and while
and other boolean operators are concerned, that result, 0
is considered false as well.
You can use this to provide a default value for example:
foo = bar or 'default'
To really convert a non-boolean value into a boolean, use the bool()
type; it uses the same rules as boolean expressions to determine the boolean value of the input:
>>> bool(0)
False
>>> bool(0.0)
False
>>> bool([])
False
>>> bool(True and 0)
False
>>> bool(1)
True
To complete the picture, values that are not considered false in a boolean context are instead considered true, including any custom classes. You can change that by implementing a .__nonzero__()
special method on your class. If no such method is defined, .__len__()
is consulted as well. With either of these methods you can signal that your type is either numeric and should be considered True
if non-zero, or it is a container and should be considered True
if not empty (has a length over 0).
Python always return one of the operand objects
and
returns the first "false" object or the final "true" object.
or
returns the first "true" object or the final "false" object.
Note that all 0
, 0.0
, False
, ""
are regarded as "false".
>>> "a" and "b" and "c"
'c'
>>> "a" or "b" or "c"
'a'
That's because 0
is s falsy value itself.
>>> bool(0)
False
>>> bool(1)
True
0 and True
is 0
because 0
is Falsy ,AND
condition stops executing as soon as first falsy value is found and returns that value. If all values were True then the rightmost value is returned.
OR
will keep on checking values until first True
is not found otherwise it returns the last value.(righmtmost)
From the docs
:
Any object can be tested for truth value, for use in an if or while condition or as operand of the Boolean operations below. The following values are considered false:
None
False
zero of any numeric type, for example,
0, 0L, 0.0, 0j
.any empty sequence, for example,
'', (), []
.any empty mapping, for example,
{}
.instances of user-defined classes, if the class defines a
__nonzero__()
or__len__()
method, when that method returns the integer zero or bool value False.
All other values are considered true — so objects of many types are always true.
Operations and built-in functions that have a Boolean result always return 0 or False for false and 1 or True for true, unless otherwise stated. (Important exception: the Boolean operations or and and always return one of their operands.)