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 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.

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.)