I'm a beginner and this is a relatively simple question but I'm having trouble trying to figure it out. When you type "True or 5" into python, it returns True, and when you type "5 or True" it returns 5. Why is this? Why don't they return the same answer? Thanks!
-
1It returns first element which is true and `bool(5)` gives `True` so it returns `5` – furas Jan 15 '17 at 20:34
-
Is the documentation not clear enough? – Stefan Pochmann Jan 15 '17 at 20:34
-
If you're referring to if you put that into the IDE, you should probably clarify so. – Torxed Jan 15 '17 at 20:34
-
short circuit evaluation. – Jean-François Fabre Jan 15 '17 at 20:39
-
Crucially: in both cases, the value it returns is truthy, so there's no difference if you do `if 5 or True:` vs `if True or 5:`. – jonrsharpe Jan 15 '17 at 20:51
3 Answers
Basically what happens with or
is it looks to the left operand and evaluates bool(..)
on it. If that returns True
, the left operand is returned. Otherwise the right operand is returned.
So
a or b
Is equivalent with:
if bool(a):
return a
else:
return b
And chaining results in a chain of if
statements like:
a or b or c or d
is equivalent to:
if bool(a):
return a
elif bool(b):
return b
elif bool(c):
return c
else:
return d
As you might notice, if you do the math with booleans, you see or
indeed behaves as a logical or operator. But it is more advanced in the sense that you can feed it all kinds of values.
For bool(..)
the standard builtin bool(..)
is used.
The same holds for and
by the way:
a and b
Is equivalent with:
if not bool(a):
return a
else:
return b

- 443,496
- 30
- 428
- 555
-
@StefanPochmann: well internally `bool(..)` [calls these functions](http://stackoverflow.com/questions/8205558/defining-boolness-of-a-class-in-python). So `bool(..)` is equivalent to your `__bool__()` in Python3 and guess what, even to `__nonzero__()` in Python2. This answer however is Python-version invariant and it says *equivalent*. Evidently things are more complicated under the interpreter hood. – Willem Van Onsem Jan 15 '17 at 20:45
-
What do you mean with redefining `bool`. Yeah indeed if I write somewhere redefine let's say `list(..)` or `all(..)`, etc. that will indeed also alter a Python program. Evidently I mean the builtin [`bool(..)`](https://docs.python.org/3/library/functions.html#bool) function. – Willem Van Onsem Jan 15 '17 at 20:54
-
Furthermore if you query `dir(type([]))`, you will see that **a list has no `__bool__` function**. In that case `bool(..)` will query the `__len__` function and check if it is greater. So in fact **`or` does not use `__bool__` since otherwise it could not work with lists**. – Willem Van Onsem Jan 15 '17 at 20:55
-
@StefanPochmann: a list evaluates to `False` if it is empty as do all builtin collections. So `[] or [1]` will evaluate to `[1]` because `bool([])` is `False`. [This](https://docs.python.org/3/library/stdtypes.html#truth) is the specification for the *truth* test which is used by `and` and `or` as well. Whether they call `bool(..)` explicitly or hardwire it, is more an interpreter detail I think. – Willem Van Onsem Jan 15 '17 at 21:07
-
@StefanPochmann: well since a list does not have a `__bool__`, but it has a `__len__` it means that somehow there must be logic in the `and`/`or` to check this and call this. If you write a custom class yourself and only implement the `__len__` that will work as well. So `and` and `or` do not directly call `__bool__` there is some magic that is at least *functionally* speaking equvalent to the builtin `bool(..)` – Willem Van Onsem Jan 15 '17 at 21:10
-
@StefanPochmann: another experiment I did was defining classes `Foo` and `Bar` they do not implement `__bool__` but implement `__len__` (`Foo` always returns `0`, `Bar` returns `2`), the query `Foo() or Bar()` returns a `Bar` object. So I think you cannot say that `and` and `or` use `__bool__` directly, they use logic that is *completely equivalent* to `bool(..)` – Willem Van Onsem Jan 15 '17 at 21:13
The or
operator short-circuits when the first value is truthy (i.e. evaluates to True
). When that happens, that first value is returned.
So, True or 5
short-circuits on the True
, so it returns True
. 5 or True
short-circuits on the 5
(because 5 is truthy, which is nonzero for integers), so it returns 5
.

- 16,979
- 16
- 61
- 94
-
Similarly, if you try to do `print("one" and "two")` it will always print two, because that is the last value checked. – RnRoger Jan 15 '17 at 20:36
or
returns the first operand that's truthy (or the last operand if they're both falsy). This can be used to check for the validity of data, and default if a value is, say, None
.
a = None
b = a or "some default"
b
'some default'
Especially in languages like JavaScript, this is a common idiom to give a function optional parameters.

- 43,494
- 9
- 68
- 117