Python has a useful feature called short circuit evaluation that acts on logical operators
Consider this code:
x = 5 y = 10 if x > 6 or y < 20: print('OK')
When Python reaches the if statement, it starts evaluating the terms from left to right:
x > 6is false
y < 20is true
orexpression is true
Now compare this code:
x = 7 y = 10 if x > 6 or y < 20: print('OK')
x > 6is true
orexpression is true
In this case, as soon as Python discovers that
x is greater than 6, it knows that the whole
or statement is true, so it doesn't bother checking
y. It doesn't matter whether
y is less than 20 or not, it won't affect the outcome because an
or statement is always true if either of the terms is true.
Python guarantees not to evaluate the second term if the first term is true.
Short circuiting with the
and operator works in a similar way.
x = 5 y = 10 if x > 6 and y < 20: print('OK')
In this case:
x > 6is false
andexpression is false
In this case, Python never evaluates
y < 20 because it already knows the final result will be false.
orstatement stops as soon as if encounters the first
andstatement stops as soon as if encounters the first
We can often use short circuit evaluation to avoid errors. A common case is checking for a value being 0 before performing a calculation:
n = 3 m = 2 if m < 1/n: print('m < 1/n')
This code looks alright at first glance. But what happens if
n is zero? Dividing by zero is an error, so our code would thrown an exception and stop working.
A quick way to avoid this is to use short circuiting, with the
n = 0 m = 2 if n and m < 1/n: print('m < 1/n')
With this new code, we have an
and expression. The first term in
n is 0, which of course counts as false, Python knows that the whole an expression is false, so it never evaluates
1/n and there is no error.
n is not zero, Python evaluates the second expression as normal.
You need to take care with this technique. Although we have successfully avoided throwing a divide by zero error, we have also ignored the fact that
nis zero. This could lead to further errors in other parts of the code.
You might expect the value of a logical expression to always be
False, but in fact this isn't the case. Python does something more useful.
a = 0 b = 2 c = 3 x = c or a: print(x)
You may be surprised to see it print 3.
What actually happens is that Python prints the last value it evaluates. In this case, Python evaluates
c, which has a value 3. Since this counts as true, it doesn't need to evaluate
a, so it returns the value 3.
Here are some more examples, using the same values of
x = a or b: print(x) #prints 2 x = b or c: print(x) #prints 2 x = 0 or a: print(x) #prints 0 (the result is false because 0 and a are both false) x = a or b+c or b+a: print(x) #prints 5 (b+c, the first true value)
Here is a real life example:
username='' username = username or input('Enter username')
In this case, the
or statement first evaluates
username, which is an empty string, so it counts as false. It then evaluates the
input statement - that is, it calls the
input function, waits for the user to type in their name, and returns that value.
If we were to execute this statement again, later, when
username has a value, the
or expression would simply return the current value, and would not call
input() at all.
It doesn't usually matter that
b gives a value of 2 rather than
True, because it works fine in an if statement.
If you really need to, you can always use the
bool() converts any value to
Copyright (c) Axlesoft Ltd 2020