Using the "or" Boolean Operator in Python (original) (raw)

Watch Now This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: Using the Python or Operator

There are three Boolean operators in Python: and, or, and not. With them, you can test conditions and decide which execution path your programs will take. In this tutorial, you’ll learn about the Python or operator and how to use it.

By the end of this tutorial, you’ll have learned:

You’ll learn how to use the Python or operator by building some practical examples. Even if you don’t really use all the possibilities that the Python or operator offers, mastering it will allow you to write better code.

Boolean Logic

George Boole (1815–1864) developed what is now called Boolean algebra, which is the foundation of the digital logic behind computer hardware and programming languages.

Boolean algebra is built around the truth value of expressions and objects (whether they are true or false) and is based in the Boolean operations AND, OR, and NOT. These operations are implemented through logical or Boolean operators that allow you to create Boolean expressions, which are expressions that evaluate to true or false.

With the help of Boolean logic, you can evaluate conditions and decide what operations your programs will execute, depending on the truth value of those conditions. This is an important cornerstone in programming and provides you with the tools to decide the execution flow of your programs.

Let’s take a look at some of the basic concepts related to Boolean logic in Python:

Now that you have a better context on Boolean logic, let’s proceed with some more Python-specific topics.

The Python Boolean Operators

Python has three Boolean operators that are typed out as plain English words:

  1. and
  2. or
  3. not

These operators connect Boolean expressions (and objects) to create compound Boolean expressions.

The Python Boolean operators always take two Boolean expressions or two objects or a combination of them, so they’re considered binary operators.

In this tutorial, you’ll be covering the Python or operator, which is the operator that implements the logical OR operation in Python. You’ll learn how it works and how to use it.

How the Python or Operator Works

With the Boolean OR operator, you can connect two Boolean expressions into one compound expression. At least one subexpressions must be true for the compound expression to be considered true, and it doesn’t matter which. If both subexpressions are false, then the expression is false.

This is the general logic behind the OR operator. However, the Python or operator does all this and more, as you’ll see in the following sections.

Using or With Boolean Expressions

You’ll need two subexpressions to create a Boolean expression using the Python or operator as a connector. The basic syntax for a Boolean expression with or is as follows:

If at least one of the subexpressions (exp1 or exp2) evaluates to True, then the expression is considered to be True. If both subexpressions evaluate to False, then the expression is False. This definition is called inclusive or, since it allows both possibilities as well as either.

Here’s a summary of the Python or operator’s behavior:

Result of exp1 Result of exp2 Result of exp1 or exp2
True True True
True False True
False True True
False False False

Table 1. Logical Python or Operator: Truth Table

This table summarizes the resulting truth value of a Boolean expression like exp1 or exp2 depending on the truth values of its subexpressions.

Let’s illustrate the resulting truth values shown in Table 1 by coding some practical examples:

In the previous examples, whenever a subexpression is evaluated to True, the global result is True. On the other hand, if both subexpressions are evaluated to False, then the global result is also False.

Using or With Common Objects

In general, the operands of an expression involving an OR operation should have Boolean values as shown in Table 1 and return a truth value as a result. When it comes to objects, Python is not very strict about that and internally implements a set of rules to decide if an object is considered true or false:

By default, an object is considered true unless its class defines either a __bool__() method that returns False or a __len__() method that returns zero, when called with the object. Here are most of the built-in objects considered false:

(Source)

If the operands involved in an or operation are objects instead of Boolean expressions, then the Python or operator returns a true or false object, not the values True or False as you could expect. The truth value of this object is determined according to the rules you’ve seen before.

This means that Python doesn’t coerce the result of an or operation to a bool object. If you’re testing two objects using or in Python, then the operator will return the first object that evaluates to true or the last object in the expression, regardless of its truth value:

In the two first examples, the first operands (2 and 5) are true (nonzero), so the Python or operator always returns the first one.

In the last two examples, the left operand is false (an empty object). The Python or operator evaluates both operands and returns the object on the right, which may evaluate to either true or false.

You can summarize the behavior shown in the previous code as follows:

Left Object Right Object Result of x or y
x y x, if it evaluates to true, otherwise y.

Table 2. Python or Operator Behavior When Testing Objects Instead of Boolean Expressions

In short, the Python or operator returns the first object that evaluates to true or the last object in the expression, regardless of its truth value.

You can generalize this behavior by chaining several operations in a single expression like this:

In this example, the Python or operator returns the first true operand it finds, or the last one. This is the rule of thumb to memorize how or works in Python.

Mixing Boolean Expressions and Objects

You can also combine Boolean expressions and common Python objects in an or operation. In this case, the Python or operator will still return the first true operand or the last operand, but the returned value could be True or False or the object you’re testing:

Result of Expression Result of Object Result of exp or obj
True True True
True False True
False False obj
False True obj

Table 3. Python or Operator Behavior When Testing Objects and Boolean Expressions

Let’s see how this works with some examples:

In Case 1 and Case 2, the subexpression 2 < 4 was evaluated to True, and the returned value was True. On the other hand, in Case 3 and Case 4, the subexpression 5 > 10 was evaluated to False, so the last operand was returned, and you got an empty list ([]) and an integer (4) instead of True or False.

As an exercise, you could try to extend Table 3 by reversing the order of the expressions in the third column, that is, use obj or exp and try to predict the results.

Short-Circuit Evaluation

Python can sometimes determine the truth value of a Boolean expression before it has evaluated all the subexpressions and objects involved. The Python or operator, for instance, stops evaluating operands as soon as it finds something that’s considered true. For example, the following expression is always True:

If the first operand in an or expression evaluates to true, regardless of the value of the second operand (4 < 3 is False), then the expression is considered to be true, and the second operand is never evaluated. This is called short-circuit (lazy) evaluation.

Let’s consider another example:

In Case 1, Python evaluated true_func(). Since it returns True, the next operand (false_func()) is not evaluated. Notice that the phrase Running false_func() is never printed. Finally, the whole expression is considered True.

Case 2 evaluates both functions, because the first operand (false_func()) is False. Then the operator returns the second result, that is, the value returned by true_func(), which is True.

Case 3 evaluates both functions, because both return False. The operation returns the last function’s return value, that is False, and the expression is considered to be False.

In Case 4, Python only evaluates the first function, which is True, and the expression is True.

In short-circuit (lazy) evaluation, the second operand on a Boolean expression is not evaluated if the value of the expression can be determined from the first operand alone. Python (like other languages) bypasses this second evaluation in favor of performance, because evaluating the second operand would be an unnecessary waste of CPU time.

Finally, when it comes to performance when you’re using the Python or operator, consider the follow:

Section Recap

You’ve learned how the Python or operator works and have seen some of its main features and behaviors. You now know enough to continue leveling up by learning how to use the operator in solving real-world problems.

Before that, let’s recap some important points about or in Python:

Now it’s time to learn where and how you can use this operator with the help of some examples.

Boolean Contexts

In this section, you’ll see some practical examples of how to use the Python or operator, and learn how to take advantage of its somewhat unusual behavior to write better Python code.

There are two main situations where you can say you’re working in a Boolean context in Python:

  1. if statements: conditional execution
  2. while loops: conditional repetition

With an if statement, you can decide your programs’ path of execution depending on the truth value of some conditions.

On the other hand, while loops allow you to repeat a piece of code as long as a given condition remains true.

These two structures are part of what you’d call control flow statements. They help you decide your programs’ execution path.

You can use the Python or operator to build Boolean expressions suitable for use with both if statement and while loops, as you’ll see in the next two sections.

if Statements

Let’s say you want to make sure that one of two conditions (or both) is true before you choose a certain path of execution. In this case, you can use the Python or operator to connect the conditions in one expression, and use that expression in an if statement.

Suppose you need to get a confirmation from the user to run some actions depending on the user’s answer:

Here, you get the user’s input and assign it to ans. Then, the if statement starts checking the conditions from left to right. If at least one of them is evaluated to true, then it executes the if code block. The elif statement does the same.

In the first call to answer(), the user’s input was y, which satisfied the first condition, and the if code block was executed. In the second call, the user’s input (n) satisfied the second condition, so the elif code block ran. If the user input doesn’t satisfy any condition, then no code block is executed.

Another example could be when you’re trying to determine whether a number is outside a range. In this case, it’s also possible to use the Python or operator. The following code tests whether x is outside the range of 20 through 40:

When you call my_range() with x=25, the if statement tests 25 < 20, which is False. Then it tests x > 40, which is also False. The final result is False, so the else block was executed.

On the other hand, 18 < 20 is evaluated to True. Then the Python or operator makes short-circuit evaluation, and the condition is considered to be True. The main block is executed, and the value is outside the range.

while Loops

while loops are another example of Boolean context where you can use the Python or operator. By using or in the loop’s header, you can test several conditions and run the body until all the conditions evaluate to false.

Suppose you need to measure the operating temperature of some industrial equipment until it gets into a range of 100 ºF to 140 ºF. To do so, you can use a while loop:

This is a toy example almost in pseudo code, but it illustrates the idea. Here, the while loop is running until temp is between 100 ºF and 140 ºF. If the temperature value is outside the range, then the loop’s body is run, and you’ll be measuring the temperature again. Once measure_temp() returns a value between 100 ºF and 140 ºF, the loop finishes. The temperature measurement is taken every 30 seconds by using sleep(30).

Non-Boolean Contexts

You can take advantage of the special features of the Python or operator out of Boolean contexts. The rule of thumb is still that the result of your Boolean expressions is the first true operand or the last in the line.

Notice that the logical operators (or included) are evaluated before the assignment operator (=), so you can assign the result of a Boolean expression to a variable in the same way you do with a common expression:

Here, the or operator works as expected, returning the first true operand or the last operand if both are evaluated to false.

You can take advantage of this somewhat special behavior of or in Python to implement a Pythonic solution to some quite common programming problems. Let’s take a look at some real-world examples.

Default Values for Variables

One common way to use the Python or operator is to select an object from a set of objects according to its truth value. You can do this by using an assignment statement:

Here, you assigned to x the first true object in the expression. If all objects (a and b in this case) are false objects, then the Python or operator returns None, which is the last operand. This works because the or operator returns one of its operands depending on their truth value.

You can also use this feature to assign a default value to your variables. The following example sets x to a if a is true, and to default otherwise:

In the previous code, you assign a to x only if a is evaluated to true. Otherwise, x is assigned default.

Default return Values

You can manipulate the return value of some built-in functions at call time. Functions like max() and min(), which take an iterable as an argument and return a single value, could be your perfect candidate for this sort of hack.

If you supply an empty iterable to max() or min(), then you’ll get a ValueError. However, you can modify this behavior by using the Python or operator. Let’s take a look at the following code:

The default behavior of max() and min() is to raise a ValueError if you call them with an empty iterable. However, by using the Python or operator, you supply a default return value for these functions and override their default behavior.

Mutable Default Arguments

A common problem beginner Python programmers face is to try to use mutable objects as default arguments to functions.

Mutable values for default arguments can retain state between calls. This is often unexpected. It happens because default argument values are evaluated and saved only once, that is, when the def statement is run, not each time the resulting function is called. That’s why you need to be careful about changing mutable defaults inside functions.

Consider the following example:

Here, every call to mutable_default() appends 1 to the end of lst, because lst holds a reference to the same object (the default []). You don’t get a new list every time the function is called as you would expect.

If that’s not the behavior you want, then the traditional (and safest) solution is to move the default to the body of the function:

With this implementation, you are ensuring that lst is set to an empty list every time you call mutable_default() with no argument, relying in the default value for lst.

The if statement in this example could almost be replaced by the assignment lst = lst or []. This way, if no argument is passed in to the function, then lst would default to None and the Python or operator would return the empty list on the right:

However, this isn’t exactly the same. For example, if an empty list is passed in, then the or operation would cause the function to modify and print a newly created list, rather than modifying and printing the originally passed-in list like the if version would do.

If you are pretty sure that you’ll only be using non-empty list objects, then you can use this approach. Otherwise, stick to the if version.

Zero Division

Zero division can be a common problem when you’re dealing with numeric calculations. To avoid this problem, it’s likely that you end up checking if the denominator is equal to 0 or not by using an if statement.

Let’s take a look at an example:

Here, you tested if the denominator (b) was not equal to 0, and then you returned the result of the division operation. If b == 0 is evaluated to True, then divide() implicitly returns None. Let’s see how to get a similar result, but this time using the Python or operator:

In this case, the Python or operator evaluates the first subexpression (b == 0). Only if this subexpression is False, the second subexpression (a / b) is evaluated, and the final result will be the division of a and b.

The difference with the previous example is that, if b == 0 is evaluated to True, then divide() returns True instead of the implicit None.

Multiple Expressions in lambda

Python provides lambda expressions, which allow you to create simple anonymous functions. The expression lambda parameters: expression yields a function object. This kind of function may be useful if you want to define simple callback and key functions.

The most common pattern for you to write a lambda function is to use a single expression as a return value. However, you can change this and let lambda execute several expressions by using the Python or operator:

With this example, you’ve forced lambda to run two expressions (print(hello, end=' ') and print(world)). But how does this code work? Well, here lambda runs a Boolean expression where two functions are executed.

When or evaluates the first function, it receives None, which is the implicit return value for print(). Since None is considered to be false, or continues to evaluate its second operand, and finally returns it as a result for the Boolean expression.

In this case, the value returned by the Boolean expression is also the value returned by lambda:

Here, result holds a reference to the value returned by lambda, which is the same value returned by the Boolean expression.

Conclusion

You now know how the Python or operator works as well as how to use it for solving some common programming problems in Python.

Now that you know the basics of the Python or operator, you’ll be able to:

In addition, you’ve learned a little bit about Boolean logic, as well as some of its main concepts in Python.

Watch Now This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: Using the Python or Operator