Using the "and" Boolean Operator in Python

Using the "and" Boolean Operator in Python

by Leodanis Pozo Ramos Updated Reading time estimate 32m basics best-practices python

Python has three Boolean operators, or logical operators: and, or, and not. You can use them to check if certain conditions are met before deciding the execution path your programs will follow. In this tutorial, you’ll learn about the and operator and how to use it in your code.

In this tutorial, you’ll learn how to:

  • Understand the logic behind Python’s and operator
  • Build and understand Boolean and non-Boolean expressions that use the and operator
  • Use the and operator in Boolean contexts to decide the course of action of your programs
  • Use the and operator in non-Boolean contexts to make your code more concise

You’ll also code a few practical examples that will help you understand how to use the and operator to approach different problems in a Pythonic way. Even if you don’t use all the features of and, learning about them will allow you to write better and more accurate code.

Working With Boolean Logic in Python

Back in 1854, George Boole authored The Laws of Thought, which contains what’s known as Boolean algebra. This algebra relies on two values: true and false. It also defines a set of Boolean operations, also known as logical operations, denoted by the generic operators AND, OR, and NOT.

These Boolean values and operators are pretty helpful in programming. For example, you can construct arbitrarily complex Boolean expressions with the operators and determine their resulting truth value as true or false. You can use the truth value of Boolean expressions to decide the course of action of your programs.

In Python, the Boolean type bool is a subclass of int and can take the values True or False:

Language: Python
>>> issubclass(bool, int)
True
>>> help(bool)
Help on class bool in module builtins:

class bool(int)
    ...

>>> type(True)
<class 'bool'>
>>> type(False)
<class 'bool'>

>>> isinstance(True, int)
True
>>> isinstance(False, int)
True

>>> int(True)
1
>>> int(False)
0

As you can see in this code, Python implements bool as a subclass of int with two possible values, True and False. These values are built-in constants in Python. They’re internally implemented as integer numbers with the value 1 for True and 0 for False. Note that both True and False must be capitalized.

Along with the bool type, Python provides three Boolean operators, or logical operators, that allow you to combine Boolean expressions and objects into more elaborate expressions. Those operators are the following:

Operator Logical Operation
and Conjunction
or Disjunction
not Negation

With these operators, you can connect several Boolean expressions and objects to build your own expressions. Unlike other languages, Python uses English words to denote Boolean operators. These words are keywords of the language, so you can’t use them as identifiers.

In this tutorial, you’ll learn about Python’s and operator. This operator implements the logical AND operation. You’ll learn how it works and how to use it either in a Boolean or non-Boolean context.

Getting Started With Python’s and Operator

Python’s and operator takes two operands, which can be Boolean expressions, objects, or a combination. With those operands, the and operator builds more elaborate expressions. The operands in an and expression are commonly known as conditions. If both conditions are true, then the and expression returns a true result. Otherwise, it returns a false result:

Language: Python
>>> True and True
True

>>> False and False
False

>>> True and False
False

>>> False and True
False

These examples show that an and expression only returns True when both operands in the expressions are true. Since the and operator takes two operands to build an expression, it’s a binary operator.

The quick examples above show what’s known as the and operator’s truth table:

operand1 operand2 operand1 and operand2
True True True
True False False
False False False
False True False

This table summarizes the resulting truth value of a Boolean expression like operand1 and operand2. The result of the expression depends on the truth values of its operands. It’ll be true if both are true. Otherwise, it’ll be false. This is the general logic behind the and operator. However, this operator can do more than that in Python.

In the following sections, you’ll learn how to use and for building your own expressions with different types of operands.

Using Python’s and Operator With Boolean Expressions

You’ll typically use logical operators to build compound Boolean expressions, which are combinations of variables and values that produce a Boolean value as a result. In other words, Boolean expressions return True or False.

Comparisons and equality tests are common examples of this type of expression:

Language: Python
>>> 5 == 3 + 2
True
>>> 5 > 3
True
>>> 5 < 3
False
>>> 5 != 3
True

>>> [5, 3] == [5, 3]
True

>>> "hi" == "hello"
False

All these expressions return True or False, which means they’re Boolean expressions. You can combine them using the and keyword to create compound expressions that test two—or more–subexpressions at a time:

Language: Python
>>> 5 > 3 and 5 == 3 + 2
True

>>> 5 < 3 and 5 == 5
False

>>> 5 == 5 and 5 != 5
False

>>> 5 < 3 and 5 != 5
False

Here, when you combine two True expressions, you get True as a result. Any other combination returns False. From these examples, you can conclude that the syntax for creating compound Boolean expressions with the and operator is the following:

Language: Python
expression1 and expression2

If both subexpressions expression1 and expression2 evaluate to True, then the compound expression is True. If at least one subexpression evaluates to False, then the result is False.

There’s no limit to the number of and operators you can use when you’re building a compound expression. This means that you can combine more than two subexpressions in a single expression using several and operators:

Language: Python
>>> 5 > 3 and 5 == 3 + 2 and 5 != 3
True

>>> 5 < 3 and 5 == 3 and 5 != 3
False

Again, if all the subexpressions evaluate to True, then you get True. Otherwise, you get False. Especially as expressions get longer, you should keep in mind that Python evaluates the expressions sequentially from left to right.

Short-Circuiting the Evaluation

Python’s logical operators, such as and and or, use something called short-circuit evaluation, or lazy evaluation. In other words, Python evaluates the operand on the right only when it needs to.

To determine the final result of an and expression, Python starts by evaluating the left operand. If it’s false, then the whole expression is false. In this situation, there’s no need to evaluate the operand on the right. Python already knows the final result.

Having a false left operand automatically makes the whole expression false. It would be a waste of CPU time to evaluate the remaining operand. Python prevents this by short-circuiting the evaluation.

In contrast, the and operator evaluates the operand on the right only if the first operand is true. In this case, the final result depends on the right operand’s truth value. If it’s true, then the whole expression is true. Otherwise, the expression is false.

To demonstrate the short-circuiting feature, take a look at the following examples:

Language: Python
>>> def true_func():
...     print("Running true_func()")
...     return True
...

>>> def false_func():
...     print("Running false_func()")
...     return False
...

>>> true_func() and false_func()  # Case 1
Running true_func()
Running false_func()
False

>>> false_func() and true_func()  # Case 2
Running false_func()
False

>>> false_func() and false_func()  # Case 3
Running false_func()
False

>>> true_func() and true_func()  # Case 4
Running true_func()
Running true_func()
True

Here’s how this code works:

  • Case 1: Python evaluates true_func(), which returns True. To determine the final result, Python evaluates false_func() and gets False. You can confirm this by seeing both functions’ output.
  • Case 2: Python evaluates false_func(), which returns False. Python already knows that the final result is False, so it doesn’t evaluate true_func().
  • Case 3: Python runs false_func() and gets False as a result. It doesn’t need to evaluate the repeated function a second time.
  • Case 4: Python evaluates true_func() and gets True as a result. It then evaluates the function again. Since both operands evaluate to True, the final result is True.

Python processes Boolean expressions from left to right. It stops when it no longer needs to evaluate any further operands or subexpressions to determine the final outcome. To sum up this concept, you should remember that if the left operand in an and expression is false, then the right operand won’t be evaluated.

Short-circuit evaluation can have a significant impact on your code’s performance. To take advantage of that, consider the following tips when you’re building and expressions:

  • Place time-consuming expressions on the right of the and keyword. This way, the costly expression won’t run if the short-circuit rule takes effect.
  • Place the expression that is more likely to be false on the left of the and keyword. This way, it’s more likely that Python can determine if the whole expression is false by evaluating the left operand only.

Sometimes you may want to avoid lazy evaluation in a specific Boolean expression. You can do so by using the bitwise operators (&, |, ~). These operators also work in Boolean expressions, but they evaluate the operands eagerly:

Language: Python
>>> def true_func():
...     print("Running true_func()")
...     return True
...

>>> def false_func():
...     print("Running false_func()")
...     return False
...

>>> # Use logical and
>>> false_func() and true_func()
Running false_func()
False

>>> # Use bitwise and
>>> false_func() & true_func()
Running false_func()
Running true_func()
False

In the first expression, the and operator works lazily, as expected. It evaluates the first function, and since the result is false, it doesn’t evaluate the second function. In the second expression, however, the bitwise AND operator (&) calls both functions eagerly even though the first function returns False. Note that in both cases, the final result is False.

Even though this trick works, it’s generally discouraged. You should use bitwise operators to manipulate bits, and Boolean operators to work with Boolean values and expressions. For a deeper dive into bitwise operators, check out Bitwise Operators in Python.

Using Python’s and Operator With Common Objects

You can use the and operator to combine two Python objects in a single expression. In that situation, Python internally uses bool() to determine the truth value of the operands. As a result, you get a specific object rather than a Boolean value. You only get True or False if a given operand explicitly evaluates to True or False:

Language: Python
>>> 2 and 3
3

>>> 5 and 0.0
0.0

>>> [] and 3
[]

>>> 0 and {}
0

>>> False and ""
False

In these examples, the and expression returns the operand on the left if it evaluates to False. Otherwise, it returns the operand on the right. To produce these results, the and operator uses Python’s internal rules to determine an object’s truth value. The Python documentation states these rules like this:

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:

  • constants defined to be false: None and False.
  • zero of any numeric type: 0, 0.0, 0j, Decimal(0), Fraction(0, 1)
  • empty sequences and collections: '', (), [], {}, set(), range(0)

(Source)

With these rules in mind, look again at the code above. In the first example, the integer number 2 is true (nonzero), so and returns the right operand, 3. In the second example, 5 is true, so and returns the right operand even though it evaluates to False.

The next example uses an empty list ([]) as the left operand. Since empty lists evaluate to false, the and expression returns the empty list. The only case where you get True or False is the one where you use a Boolean object explicitly in the expression.

Here’s how you can summarize the behavior of the and operator when you use it with common Python objects instead of Boolean expressions. Note that Python uses the truth value of each object to determine the final result:

object1 object2 object1 and object2
False False object1
False True object1
True True object2
True False object2

In general, if the operands in an and expression are objects instead of Boolean expressions, then the operator returns the object on the left if it evaluates to False. Otherwise, it returns the object on the right, even when it evaluates to False.

Mixing Boolean Expressions and Objects

You can also combine Boolean expressions and common Python objects within an and expression. In that situation, the and expression still returns the left operand if it’s false, or else it returns the right operand. The returned value could be True, False, or a regular object, depending on which part of the expression provides that result:

Language: Python
>>> 2 < 4 and 2
2
>>> 2 and 2 < 4
True

>>> 2 < 4 and []
[]
>>> [] and 2 < 4
[]

>>> 5 > 10 and {}
False
>>> {} and 5 > 10
{}

>>> 5 > 10 and 4
False
>>> 4 and 5 > 10
False

These examples use a combination of Boolean expressions and common objects. In each pair of examples, you see that you can get either a non-Boolean object or a Boolean value, True or False. The result will depend on which part of the expression provides the final result.

Here’s a table that summarizes the behavior of the and operator when you combine Boolean expressions and common Python objects:

expression object expression and object
True True object
True False object
False False False
False True False

To find out what’s returned, Python evaluates the Boolean expression on the left to get its Boolean value (True or False). Then Python uses its internal rules to determine the truth value of the object on the right.

As an exercise to test your understanding, you could try to rewrite this table by swapping the order of the operands in the third column to object and expression. Try to predict what will be returned in each row.

Combining Python Logical Operators

As you’ve seen earlier in this tutorial, Python provides two additional logical operators: the or operator and the not operator. You can use them along with the and operator to create more complex compound expressions. If you want to make accurate and clear expressions with multiple logical operators, then you need to consider the precedence of each operator. In other words, you need to consider the order in which Python executes them.

Python’s logical operators have low precedence when compared with other operators. However, sometimes it’s healthy to use a pair of parentheses (()) to ensure a consistent and readable result:

Language: Python
>>> 5 or 2 and 2 > 1
5

>>> (5 or 3) and 2 > 1
True

These examples combine the or operator and the and operator in a compound expression. Just like the and operator, the or operator uses short-circuit evaluation. Unlike and, however, the or operator stops once it finds a true operand. You can see this in the first example. Since 5 is true, the or subexpression immediately returns 5 without evaluating the rest of the expression.

In contrast, if you enclose the or subexpression in a pair of parentheses, then it works as a single true operand, and 2 > 1 gets evaluated as well. The final result is True.

The takeaway is that if you’re using multiple logical operators in a single expression, then you should consider using parentheses to make your intentions clear. This trick will also help you get the correct logical result.

Using Python’s and Operator in Boolean Contexts

Like all of Python’s Boolean operators, the and operator is especially useful in Boolean contexts. Boolean contexts are where you’ll find most of the real-world use cases of Boolean operators.

Two main structures define Boolean contexts in Python:

  1. if statements let you perform conditional execution and take different courses of action based on the result of some initial conditions.
  2. while loops let you perform conditional iteration and run repetitive tasks while a given condition is 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 Python’s and operator to construct compound Boolean expressions in both if statements and while loops.

if Statements

Boolean expressions are commonly known as conditions because they typically imply the need for meeting a given requirement. They’re pretty useful in the context of conditional statements. In Python, this type of statement starts with the if keyword and continues with a condition. A conditional statement can additionally include elif and else clauses.

Python conditional statements follow the logic of conditionals in English grammar. If the condition is true, then the if code block executes. Otherwise, the execution jumps to a different code block:

Language: Python
>>> a = -8

>>> if a < 0:
...     print("a is negative")
... elif a > 0:
...     print("a is positive")
... else:
...     print("a is equal to 0")
...
a is negative

Since a holds a negative number, the condition a < 0 is true. The if code block runs, and you get the message a is negative printed on your screen. If you change the value of a to a positive number, however, then the elif block runs and Python prints a is positive. Finally, if you set a to zero, then the else code block executes. Go ahead and play with a to see what happens!

Now say you want to make sure that two conditions are met—meaning that they’re both true—before running a certain piece of code. To try this out, suppose you need to get the age of a user running your script, process that information, and display to the user their current life stage.

Fire up your favorite code editor or IDE and create the following script:

Language: Python
# age.py

age = int(input("Enter your age: "))

if age >= 0 and age <= 9:
    print("You are a child!")
elif age > 9 and age <= 18:
    print("You are an adolescent!")
elif age > 18 and age <= 65:
    print("You are an adult!")
elif age > 65:
    print("Golden ages!")

Here, you get the user’s age using input() and then convert it to an integer number with int(). The if clause checks if age is greater than or equal to 0. In the same clause, it checks if age is less than or equal to 9. To do this, you build an and compound Boolean expression.

The three elif clauses check other intervals to determine the life stage associated with the user’s age.

If you run this script from your command line, then you get something like this:

Language: Shell
$ python age.py
Enter your age: 25
You are an adult!

Depending on the age you enter at the command line, the script takes one course of action or another. In this specific example, you provide an age of 25 years and get the message You are an adult! printed to your screen.

while Loops

The while loop is the second construct that can use and expressions to control a program’s execution flow. By using the and operator in the while statement header, you can test several conditions and repeat the loop’s code block for as long as all conditions are met.

Say you’re prototyping a control system for a manufacturer. The system has a critical mechanism that should work with a pressure of 500 psi or lower. If the pressure goes over 500 psi while staying under 700 psi, then the system has to run a given series of standard safety actions. For pressures greater than 700 psi, there are a whole new set of safety actions that the system must run.

To approach this problem, you can use a while loop with an and expression. Here’s a script that simulates a possible solution:

Language: Python
 1# pressure.py
 2
 3from time import sleep
 4from random import randint
 5
 6def control_pressure():
 7    pressure = measure_pressure()
 8    while True:
 9        if pressure <= 500:
10            break
11
12        while pressure > 500 and pressure <= 700:
13            run_standard_safeties()
14            pressure = measure_pressure()
15
16        while pressure > 700:
17            run_critical_safeties()
18            pressure = measure_pressure()
19
20    print("Wow! The system is safe...")
21
22def measure_pressure():
23    pressure = randint(490, 800)
24    print(f"psi={pressure}", end="; ")
25    return pressure
26
27def run_standard_safeties():
28    print("Running standard safeties...")
29    sleep(0.2)
30
31def run_critical_safeties():
32    print("Running critical safeties...")
33    sleep(0.7)
34
35if __name__ == "__main__":
36    control_pressure()

Inside control_pressure(), you create an infinite while loop on line 8. If the system is stable and the pressure is below 500 psi, the conditional statement breaks out of the loop and the program finishes.

On line 12, the first nested while loop runs the standard safety actions while the system pressure stays between 500 psi and 700 psi. In each iteration, the loop gets a new pressure measurement to test the condition again in the next iteration. If the pressure grows beyond 700 psi, then the second loop on line 16 runs the critical safety actions.