In Python, any non-zero value is evaluated as True. So, for example, the following code prints Yes
.
if 2 or 3:
print('Yes')
But, if I type 2 or 3
at the Python console I get 2
instead of True
. Why the different behavior?
In Python, any non-zero value is evaluated as True. So, for example, the following code prints Yes
.
if 2 or 3:
print('Yes')
But, if I type 2 or 3
at the Python console I get 2
instead of True
. Why the different behavior?
When using or
, Python will return the first truthy value.
print None or 2 # Prints 2
print 0 or 'Foo' # Prints Foo
print False or True # Prints True
If the first value is falsy, it will return the second one, actually no matter if it's truthy or not:
print None or False # Prints False
print False or None # Prints None
print False or 0 # Prints 0
If you chain the statements, it will evaluate the first condition first, then the second
print None or False or 0 # Will evaluate into ((None or False) or 0)
This is also possible in languages like PHP and JavaScript.
Source: https://docs.python.org/3/library/stdtypes.html#truth-value-testing
In all your cases the 2 or 3
expression is producing 2
.
It is then either displayed directly by the console, passed to the print
function, or passed to the if
statement.
The if
does its own truthiness testing.
In [14]: 2 or 3 # or returns the first truthy item
Out[14]: 2
In [15]: None or 3
Out[15]: 3
In [16]: False or 0 or 2
Out[16]: 2
print
just displays its argument:
In [17]: print(2 or 3)
2
if
does the action if its argument if truthy; does the else
if not:
In [18]: if 2: print('yes')
yes
In [19]: if False: print('yes')
Here it evaluates the or
, and then acts on the result:
In [20]: if None or 2 or 3: print('yes')
yes
and
returns the first falsy, or last if none
In [21]: 2 and 3
Out[21]: 3
In [22]: 2 and False
Out[22]: False
In [23]: 2 and 0 and 3
Out[23]: 0
or
returns the first value if the value is truthy, or the second value if the first value is falsy (source).
This behavior is sometimes used idiomatically to initialize keyword argument of mutable type:
def foo(bar=None, zoo=None):
bar = bar or []
zoo = zoo or {}
This is not the unique way to initialize them, but you should be aware you should not use empty list or dict as default argument.