# Short circuit evaluation

Martin McBride, 2018-08-23
Tags operator short circuit and or comparison operator logical operator
Categories python language intermediate python Python has a useful feature called short circuit evaluation that acts on logical operators `or` and `and`.

## Short circuiting with the or operator

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 > 6` is false
• `y < 20` is true
• therefore the result of the `or` expression is true
• the print statement executes

Now compare this code:

```x = 7
y = 10
if x > 6 or y < 20:
print('OK')
```
• `x > 6` is true
• therefore the result of the `or` expression is true
• the print statement executes

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

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 > 6` is false
• therefore the result of the `and` expression is false
• the print statement doesn't execute

In this case, Python never evaluates `y < 20` because it already knows the final result will be false.

In summary:

• An `or` statement stops as soon as if encounters the first `True` case
• An `and` statement stops as soon as if encounters the first `False` case

## Short circuiting to avoid errors

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 `and` operator:

```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`. If `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.

If `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 `n` is zero. This could lead to further errors in other parts of the code.

## The value of an or/and expression

You might expect the value of a logical expression to always be `True` or `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 `a`, `b` and `c`:

```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=''
```

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.

## Getting a true or false value

It doesn't usually matter that `a` or `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()` function. `bool()` converts any value to `True` or `False`.

If you found this article useful, you might be interested in the book Python Quick Start or other books by the same author.

#### Popular tags

2d arrays abstract data type alignment and animation arc array arrays bezier curve built-in function callable object circle classes close closure cmyk colour comparison operator comprehension context context manager conversion creational pattern data types design pattern device space dictionary drawing duck typing efficiency else encryption enumerate fill filter font font style for loop function function composition function plot functools game development generativepy tutorial generator geometry gif gradient greyscale higher order function hsl html image image processing imagesurface immutable object index inner function input installing iter iterable iterator itertools l system lambda function len line linspace list list comprehension logical operator lru_cache magic method mandelbrot mandelbrot set map monad mutability named parameter numeric python numpy object open operator optional parameter or partial application path polygon positional parameter print pure function pycairo radial gradient range recipes rectangle recursion reduce rgb rotation scaling sector segment sequence singleton slice slicing sound spirograph sprite square str stream string stroke subpath symmetric encryption template text text metrics tinkerbell fractal transform translation transparency tuple turtle unpacking user space vectorisation webserver website while loop zip