0

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?

Johan
  • 3,577
  • 1
  • 14
  • 28
Srikant
  • 139
  • 1
  • 5
  • 2
    or returns the first truthy value it encounters. In particular, it does not implicitly casts it to a boolean – Olivier Melançon Oct 02 '18 at 20:22
  • 4
    `if 2: print('Yes')` also prints "Yes", but you wouldn't expect `print(2)` to print "True", would you? – user2357112 Oct 02 '18 at 20:23
  • Based on the above two comments- should I then infer the following: (a) Typing something at the console is the equivalent of a issuing a print and (b) Python interprets a truthy-value as True only in the context of if statements. Or maybe, I am missing something very basic. – Srikant Oct 02 '18 at 20:30
  • Both (a) and (b) are wrong. – Merlin1896 Oct 02 '18 at 20:31
  • 2
    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. – hpaulj Oct 02 '18 at 20:49
  • @hpaulj Thanks. That really helped clarify what is going on. Would you mind converting that to an answer so that I can accept it? – Srikant Oct 02 '18 at 22:42

3 Answers3

3

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

Johan
  • 3,577
  • 1
  • 14
  • 28
2

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
hpaulj
  • 221,503
  • 14
  • 230
  • 353
1

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.

pietroppeter
  • 1,433
  • 13
  • 30