How do and and or act with non-boolean values?
TL;DR
We start by summarising the two behaviour of the two logical operators and
and or
. These idioms will form the basis of our discussion below.
and
Return the first Falsy value if there are any, else return the last
value in the expression.
or
Return the first Truthy value if there are any, else return the last
value in the expression.
The behaviour is also summarised in the docs, especially in this table:
Operation | Result |
---|---|
x or y | if x is false, then y, else x |
x and y | if x is false, then x, else y |
not x | if x is false, then True , else False |
How do 'and' and 'or' act with non-boolean values in Python?
This is the "and-or trick" -- and
and or
don't actually return boolean values; instead, they return one of their input arguments. People used to use this for control-flow.
As of python 2.5, it's not necessary anymore, because conditional expressions were introduced.
22 and 333/12 or 1
is equivalent to
333/12 if 22 else 1
Python: justification for boolean operators (and, or) not returning booleans
In Python's case, the bool
type didn't even exist until over a decade after the language was released. If it had existed from the start, perhaps and
and or
would have been defined differently. But, as is, backward compatibility was far more important. From the PEP that introduced the type:
Another consequence of the compatibility requirement is that the expression "True and 6" has the value 6, and similarly the expression "False or None" has the value None. The "and" and "or" operators are usefully defined to return the first argument that determines the outcome, and this won't change; in particular, they don't force the outcome to be a bool. Of course, if both arguments are bools, the outcome is always a bool. It can also easily be coerced into being a bool by writing for example "bool(x and y)".
EDIT: BTW, at its start, Python was intended to "bridge the gap" between programming in "data-rich" languages like C
and "convenient" languages like Unixy shells (sh
, csh
, etc). Python's and
and or
were more like &&
and ||
act in shell languages, consuming - left to right - all and only the operands needed to resolve whether the overall chain succeeded ("true") or failed ("false").
What does or mean inside a Python list comprehension?
Maybe this will make it easier for you to see:
actions.extend(self.get_action(action) for action in (self.actions or []))
The value of self.actions
might have been None
, i.e. it's type is an Optional[List[T]]
Using the or
operator will return the first value that evaluates as true, or return the last value it evaluated. This uses short circuit logic, meaning if you have multiple values chained together, it will stop evaluating the expression once it finds the first "truthy" value (see bottom example).
For basic semantics, consider this example:
>>> a = None
>>> b = [1,2,3]
>>> c = a or b
>>> c
[1,2,3]
This is equivalent to:
a = None
b = [1,2,3]
if a:
c = a
else:
c = b
Some more examples:
>>> a = 1
>>> b = 2
>>> a or b
1
>>> a = 1
>>> b = None
>>> a or b
1
>>> a = None
>>> b = 2
>>> a or b
2
>>> a = None
>>> b = None
>>> a or b
None
>>> a = None
>>> b = False
>>> a or b
False
>>> a = 0
>>> b = 0
>>> c = 1
>>> a or b or c
1
Note in the last example we are able to chain multiple or
calls together!
An example of short-circuiting (notice that foo(2)
does not get called!):
>>> def foo(i):
... print(f"foo: {i}")
... return i
...
>>> foo(0) or foo(1) or foo(2)
foo: 0
foo: 1
1
Using logical operators in an expression
x and y
is x
if it is "false-y" (i.e. 0
, False
, None
, []
, ''
, ...), otherwise it is y
.x or y
is x
if it is "truth-y", otherwise it is y
.
That is, x or y
is the same as x if x else y
, and x and y
the same as x if not x else y
.
Related Topics
Why Is Reading Lines from Stdin Much Slower in C++ Than Python
Decode HTML Entities in Python String
How to Select a HTML Element No Matter What Frame It Is in in Selenium
Render HTML to Pdf in Django Site
Checking If Element Exists With Python Selenium
How to Get Text of an Element in Selenium Webdriver, Without Including Child Element Text
Beautiful Soup Findall Doesn't Find Them All
Staleelementreferenceexception on Python Selenium
Convert Rgb Color to English Color Name, Like 'Green' With Python
How to Use 'Subprocess' Command With Pipes
If/Else in a List Comprehension
Are a Wsgi Server and Http Server Required to Serve a Flask App
What Are Iterator, Iterable, and Iteration
How to Make a Class Json Serializable