Skip to main content
HomeTutorialsPython

Python Logical Operators: A Hands-on Introduction

Python offers three logical operators: and, or, and not. These operators, also known as Boolean operators, evaluate multiple conditions and determine an expression's overall truth value.
May 2024  · 17 min read

In programming, we frequently need to make decisions based on multiple conditions. For instance, we might want to execute a certain action only if several conditions are met simultaneously. Alternatively, we might want to trigger an alternative action if any one of several conditions is fulfilled.

Python offers a set of logical operators – and, or, not – to handle these scenarios.

In this tutorial, we'll learn how Python logical operators work and how to use them in programming and data science. Note that we’ll use the uppercase words AND, OR, and NOT to represent these operators conceptually. And we’ll refer to the Python keywords using this convention: and, or, and not.

If you’re looking for a curated Python curriculum, check out this six-course Python Programming skill track.

Before getting into the details, let’s start with a very brief answer for those of you in a hurry.

Short Answer: What Are Python Logical Operators?

Python logical operators (and, or, not) are special keywords that act as conjunctions in our code, connecting and evaluating multiple conditions within a single expression.

Consider this example:

temperature = 25
is_sunny = True
if temperature > 20 and is_sunny:
    print("It's a perfect day for a picnic!")
It's a perfect day for a picnic!

Here, the and operator ensures that the message is printed only if both conditions are met: the temperature is above 20 degrees and it's sunny.

Let's look at another example using the or operator:

has_umbrella = False

if is_sunny or has_umbrella:
    print("Let's go for a walk!")
Let's go for a walk!

In this case, we'll head out for a walk if either it's sunny or we have an umbrella.

Finally, the not operator flips the truth value of a condition:

if not is_sunny:
    print("Maybe we should stay indoors.")

Here, the message is printed only if it is not sunny.

Logical operators give us a concise and powerful way to express complex conditions, allowing our programs to make decisions based on multiple factors. Now, let’s take a deeper look and start with the and logical operator.

Python: The and Operator

In Boolean logic, the AND operation involves comparing two values or expressions. It produces a true result only if both values are true. If either one or both of the values are false, the result of the AND operation is false. Here’s a summary of how AND behaves:

Operation

Output value

true AND true

true

true AND false

false

false AND true

false

false AND false

false

We can recreate this truth table with Python's and operator:

options = True, False
for a in options:
    for b in options:
        print(f"{a} and {b} gives {a and b}")
True and True gives True
True and False gives False
False and True gives False
False and False gives False

The options variable contains the two Boolean values. The nested for loops iterate through options twice to create all permutations of True and False.

Often, the expressions used as operands for and include comparison or equality operators:

names = "James", "Bob", "David", "Jane", "Kate", "Mary"
for name in names:
   if len(name) < 5 and name[0] == "J":
      print(name)
Jane

The name is printed out only if it contains fewer than five letters and starts with "J". Both requirements must be met.

The comparison and equality operators, such as < and ==, evaluate to True or False.

However, the Python and operator works on any data type and not just the Boolean True and False. The output value can also be any data type.

Let's explore Python's and operator in more detail in this section. First, we'll discuss truthiness.

Python: truthy and falsy

Every Python object can be converted to a Boolean type using the built-in bool(). An object is truthy if bool(object) returns True. For a falsy object, bool(object) returns False.

Python's and operator looks at the truthiness of its operands. If both operands are truthy, the and operator also returns a truthy value. If one or both operands are falsy, and returns a falsy value. Let's look at some examples:

if 42 and "python":
    print("Both operands are truthy")
else:
    print("One or both operands are falsy")
Both operands are truthy

Now, let's consider this example:

if 42 and "":
    print("Both operands are truthy")
else:
    print("One or both operands are falsy")
One or both operands are falsy

And let's take a look at this final example:

if 0 and "python":
    print("Both operands are truthy")
else:
    print("One or both operands are falsy")
One or both operands are falsy

Numeric types, like integers and floats, are truthy if they're non-zero and falsy when equal to zero. Sequences, like strings, are truthy when they're non-empty and falsy when they're empty.

Therefore, only the first of the three examples above satisfies the condition that both operands should be truthy for the and operator to evaluate to truthy.

The and operator doesn't always return a Boolean value. An expression that includes and could also evaluate to one of the operands. Let's dive into this further using the same examples we used earlier. Instead of using the and expressions in an if statement, we'll evaluate them directly:

print(42 and "python")
print(42 and "")
print(0 and "python")
python

0

Can you spot what's happening with these expressions?

Let's start with the last of the three examples, which has 0 and "python" as the two operands. The and operator is looking for two truthy operands. Since the first one is 0, it's falsy. There's no need for the program to check the second operator since the whole expression will be falsy regardless of the value of the second operand.

However, the and operator doesn't return False. Instead, it returns the first operand directly. Since the first operand is falsy, the whole and expression evaluates to falsy. This doesn't cause any issues in Python, as in situations where Python requires a true or false value, it can use the truthiness of an object.

In the first example, the first operand is 42, which is truthy. The program evaluates the second operand and returns it. Since the second operand is the string "python", which is truthy, the whole expression evaluates as truthy.

In the second example, the first operand is also 42. Since it's truthy, the program evaluates and returns the second operand, which is the empty string. The empty string is falsy, and therefore, the entire and expression evaluates to falsy.

When the first operand is truthy, the and operator always returns the value of the second operand, whether the second operand is truthy or falsy.

When the first operand is falsy, Python doesn't evaluate the second operand. This is called short-circuiting, and it's a form of lazy evaluation. You can confirm this with the following code:

0 and 5/0
0

The second operand is 5/0, which would normally raise a ZeroDivisionError. However, the 5/0 expression isn't evaluated in this example since the first operand is falsy. The exception is never raised.

Example: The Programmers' Online Store

Let's consider a simple example that represents a real-life application. Transactions in an online store that supplies goods for programmers are recorded and accessed through an API. The data are converted into a list of dictionaries. Each item in the list represents a transaction and each transaction is a dictionary containing relevant information:

data = [
{"Item": "Python Book", "Price": 50, "Quantity": 1, "Success": True},
{"Item": "Coffee Machine", "Price": 125, "Quantity": 1, "Success": False},
{"Item": "Headphones", "Price": 250, "Quantity": 1, "Success": True},
{"Item": "Cables", "Price": 15.99, "Quantity": 3, "Success": True},
]

Each transaction includes the item's name and price, the quantity included in the order, and whether the transaction was successful.

Let's assume we need successful transactions for items priced at $100 or over. We can use the and operator to filter the rows we need:

for item in data:
    if item["Success"] and item["Price"] >= 100:
        print(item)
{'Item': 'Headphones', 'Price': 250, 'Quantity': 1, 'Success': True}

The output from this code shows the only transaction that meets both requirements. For each item in the list of transactions, the if statement checks the truthiness of two expressions:

  • The values associated with the key "Success" in each dictionary are either True or False.
  • The greater than or equal to operator in item["Price"] >= 100 also returns True or False.

The Python book and the cables do not meet the price requirement as they're under $100. The coffee machine is over this price threshold, but this transaction wasn't successful, so it's excluded from the printout.

We'll return to this online store example later in this tutorial.

In the following section, we'll focus on the or operator.

Python: The or Operator

The OR logical operator in Boolean logic needs two operands. It evaluates to true if at least one of the operands is true:

Operation

Output value

true OR true

true

true OR false

true

false OR true

true

false OR false

false

We can recreate this truth table using Python's or operator:

options = True, False
for a in options:
    for b in options:
        print(f"{a} or {b} gives {a or b}")
True or True gives True
True or False gives True
False or True gives True
False or False gives False

We can also revisit the example with people's names we explored earlier but replace the and operator with an or:

names = "James", "Bob", "David", "Jane", "Kate", "Mary"
for name in names:
    if len(name) < 5 or name[0] == "J":
        print(name)
James
Bob
Jane
Kate
Mary

The if statement now contains an or expression. Therefore, the for loop prints all names that either have fewer than five letters or start with the letter "J". The string "Jane" meets both requirements. The other printed names meet one of the two requirements.

Python or operator: truthy and falsy

The or operator also looks for truthy and falsy values and not just the Booleans True and False. Let's look at some examples:

if 42 or [10, 20, 30]:
    print("At least one operand is truthy")
else:
    print("None of the operands is truthy")
At least one operand is truthy

Now let’s consider this example:

if 42 or []:
    print("At least one operand is truthy")
else:
    print("None of the operands is truthy")
At least one operand is truthy

And let’s also consider this final example:

if 0 or []:
    print("At least one operand is truthy")
else:
    print("None of the operands is truthy")
None of the operands is truthy

In the first example, the integer 42 and the non-empty list [10, 20, 30] are truthy. Since the or operator needs at least one operand to be truthy, the whole expression evaluates as truthy.

In the second example, 42 is truthy but the empty list [] is falsy since it's an empty sequence. As one of the two operands is truthy, the whole or expression evaluates as truthy.

In the final example, both 0 and [] are falsy. Therefore, the entire expression evaluates as falsy.

The or operator also uses short-circuiting when evaluating the expression to avoid unnecessary evaluations. Let's look at some examples to illustrate this point:

print(42 or [10, 20, 30])
print(42 or [])
print([] or 42)
print([] or 0)
42
42
42
0

In the first example, the first operand is 42, which is truthy. Since or only requires one operand to be truthy to determine the final truthiness of the entire expression, this first operand is returned immediately. The second operand is not evaluated as its value has no effect on the final result. The or operator returns the first operand, 42, not the Boolean True. In Python, any truthy value has the same effect as the Boolean True in situations such as if statements and while statements.

In the second example, the first operand is also 42, and the expression returns this integer even though the second operand is falsy.

In the third and fourth examples, the first operand is the empty list, which is falsy. Therefore, the second operand is returned in both cases.

Example: The Programmers' Online Store

Let's revisit the transactions from the online store that sells goods to programmers. Here are the four sample transactions we're using in this example:

data = [
{"Item": "Python Book", "Price": 50, "Quantity": 1, "Success": True},
{"Item": "Coffee Machine", "Price": 125, "Quantity": 1, "Success": False},
{"Item": "Headphones", "Price": 250, "Quantity": 1, "Success": True},
{"Item": "Cables", "Price": 15.99, "Quantity": 3, "Success": True},
]

You need to identify some transactions to investigate customer behavior further. You want to find the transactions that either failed or include an item priced below $75. Since you have two conditions and you only require a transaction to meet at least one of them, you can use the or operator:

for item in data:
    if item["Success"] == False or item["Price"] < 75:
        print(item)
{'Item': 'Python Book', 'Price': 50, 'Quantity': 1, 'Success': True}
{'Item': 'Coffee Machine', 'Price': 125, 'Quantity': 1, 'Success': False}
{'Item': 'Cables', 'Price': 15.99, 'Quantity': 3, 'Success': True}

This for loop displays the lines that match at least one of the requirements. The Python book and the cables are included as their price is below $75. The coffee machine is included since the transaction wasn't successful.

There's an alternative way of filtering the unsuccessful transactions, which we'll explore in the following section.

Python: The not Operator

The NOT operator differs from AND and OR since it only requires one operand. NOT converts true to false and the other way round. Here's the truth table for NOT:

Operation

Output value

NOT true

false

NOT false

true

We can replicate this using Python's not operator:

options = True, False
    for a in options:
        print(f"not {a} evaluates to {not a}")
not True evaluates to False
not False evaluates to True

Python not operator: truthy and falsy

As with and and or, the operand used with not doesn't have to be a Boolean. Since any object is either truthy or falsy, any object can be used with not.

if not "python":
    print("The `if` statement evaluated as `True`")
else:
    print("The `if` statement evaluated as `False`")
The `if` statement evaluated as `False`

Let’s also look at this example:

if not "":
    print("The `if` statement evaluated as `True`")
else:
    print("The `if` statement evaluated as `False`")
The `if` statement evaluated as `True`

Truthy values are converted to False with the not operator and falsy values are converted to True.

Unlike and and or, the not operator always returns a Boolean object:

print(not "python")
print(not "")
False
True

Example: The Programmers' Online Store

In the previous sections, we used the transactions from an online store. We want to display all the unsuccessful transactions in this example. One option is using the equality operator == to check whether data["Success"] equals False. However, we can also use the not operator instead:

data = [
{"Item": "Python Book", "Price": 50, "Quantity": 1, "Success": True},
{"Item": "Coffee Machine", "Price": 125, "Quantity": 1, "Success": False},
{"Item": "Headphones", "Price": 250, "Quantity": 1, "Success": True},
{"Item": "Cables", "Price": 15.99, "Quantity": 3, "Success": True},
]

for item in data: if not item["Success"]: print(item)
{'Item': 'Coffee Machine', 'Price': 125, 'Quantity': 1, 'Success': False}

Since item["Success"] is equal to False for the unsuccessful transactions, not item["Success"] returns True. Therefore, the for loop prints out the unsuccessful transactions:

In the following section, we'll learn how to combine several logical operators in one expression.

Python: Operator Precendence

In the examples shown so far, we only used one of the logical operators in each instance. In this section, we'll see what happens when we combine more logical operators in a single expression.

Python: and has precedence over or

We'll continue working on the transactions from the online store we used earlier. Let's try the following conditional statement:

data = [
{"Item": "Python Book", "Price": 50, "Quantity": 1, "Success": True},
{"Item": "Coffee Machine", "Price": 125, "Quantity": 1, "Success": False},
{"Item": "Headphones", "Price": 250, "Quantity": 1, "Success": True},
{"Item": "Cables", "Price": 15.99, "Quantity": 3, "Success": True},
]
​
for item in data:
    if item["Price"] > 100 or item["Quantity"] > 2 and item["Success"]:
        print(item)
{'Item': 'Coffee Machine', 'Price': 125, 'Quantity': 1, 'Success': False}
{'Item': 'Headphones', 'Price': 250, 'Quantity': 1, 'Success': True}
{'Item': 'Cables', 'Price': 15.99, 'Quantity': 3, 'Success': True}

The if statement contains two logical operators. Before we investigate how Python deals with this expression, let's look at an English translation of the if statement: If the item's price is over $100 or the quantity sold is greater than two and the sale was successful, then print the item.

This phrase is ambiguous without more punctuation marks and may still cause confusion even if we add more commas in the sentence. For example, should the transaction with the coffee machine be included? The item's price is over the required threshold but the transaction wasn't successful.

Python resolved this ambiguity by giving the and operator precedence over the or operator. This means that the and expression is evaluated first, and its outcome is used in the or expression.

Therefore, the expression item["Quantity"] > 2 and item["Success"] is evaluated first. This expression returns a truthy value only for the transaction including cables. It evaluates as falsy for the remaining items.

The value from the and expression is then used with the or operator. The or expression returns a truthy value for any item that returns truthy for the and expression—this was only the transaction including cables—and for items with a price over $100. There are two items with prices over the threshold: the coffee machine and the headphones.

Python: parentheses and logical operators

However, what if we need transactions with items priced above $100 or with a quantity above two, but we also want to ensure the transaction is successful? In this case, we want the or expression to take precedence over the and so that it's evaluated first. We can achieve this using parentheses around the or expression:

for item in data:
    if (item["Price"] > 100 or item["Quantity"] > 2) and item["Success"]:
        print(item)
{'Item': 'Headphones', 'Price': 250, 'Quantity': 1, 'Success': True}
{'Item': 'Cables', 'Price': 15.99, 'Quantity': 3, 'Success': True}

The additional parentheses give precedence to the or expression. The coffee machine transaction is no longer included since it evaluates falsy for the second and operand.

Python: not has precedence over and and or

The not operator takes precedence over and and or. Therefore, not is evaluated before the other two logical operators.

Let's consider the following if statement, which includes both not and and:

for item in data:
    if not item["Success"] and item["Price"] > 100:
        print(item)
{'Item': 'Coffee Machine', 'Price': 125, 'Quantity': 1, 'Success': False}

Since not is evaluated first, this expression will first apply the not operator to item["Success"]. The value from the not expression is then used as the first operand in the and expression. Only the coffee machine entry satisfies this condition—this is the only transaction that has failed and has a price over $100.

However, we can give precedence to the and operator by using parentheses:

for item in data:
    if not (item["Success"] and item["Price"] > 100):
        print(item)
{'Item': 'Python Book', 'Price': 50, 'Quantity': 1, 'Success': True}
{'Item': 'Coffee Machine', 'Price': 125, 'Quantity': 1, 'Success': False}
{'Item': 'Cables', 'Price': 15.99, 'Quantity': 3, 'Success': True}

In this case, the and expression is evaluated first. Only the entry with headphones evaluates to True since it's the only successful transaction with a price over $100. However, we add a not operator before the expression in parentheses. Therefore, the code outputs the remaining three transactions.

In general, if an expression becomes too complex because it has too many operators, it's best to split it to make it more readable.

Conclusion

The Python logical operators and, or, and not are used extensively in a broad range of programming and data science applications. These operators replicate the behavior of the AND, OR, and NOT Boolean logical operators used broadly in logic and mathematics.

However, the Python operators can accept any object and not just Boolean values. The and and or operators use short-circuit evaluation and return one of the operands as their output.

The Python logical operators are key tools to filter data, identify features in data sets, and create complex rules to control the flow of a program. If you want to learn more about this, check out this nine-course Data Analyst With Python career track.


Photo of Stephen Gruppetta
Author
Stephen Gruppetta

I studied Physics and Mathematics at UG level at the University of Malta. Then, I moved to London and got my PhD in Physics from Imperial College. I worked on novel optical techniques to image the human retina. Now, I focus on writing about Python, communicating about Python, and teaching Python.

Python Logical Operators FAQs

Can I use the and operator to test multiple conditions at once?

Yes, you can chain multiple conditions together using the and operator. For example: if x > 5 and x < 10 and x != 7.

What's the difference between the and operator and the bitwise AND operator (&)?

The and operator performs a logical AND operation on Boolean values, returning True only if both operands are True. The bitwise AND operator (&) performs a bitwise AND operation on the binary representation of integer values.

Does Python have the && and || operators like some other languages?

No, Python uses the keywords and and or instead of the symbols && and || for logical operations.

Topics

Learn more about Python and AI!

Track

Python Programming

19hrs hr
Level-up your programming skills. Learn how to optimize code, write functions and tests, and use best-practice software engineering techniques.
See DetailsRight Arrow
Start Course
See MoreRight Arrow
Related

tutorial

Operators in Python

This tutorial covers the different types of operators in Python, operator overloading, precedence and associativity.
Théo Vanderheyden's photo

Théo Vanderheyden

9 min

tutorial

Exploring the Python 'Not Equal' Operator

Comparing values in Python to check if they are not equal is simple with the not equal operator. Check out this quick tutorial on how to use the not equal Python operator, as well as alternatives for comparing floats.
Amberle McKee's photo

Amberle McKee

5 min

tutorial

Operators in R

Learn how to use arithmetic and logical operators in R. These binary operators work on vectors, matrices, and scalars.
DataCamp Team's photo

DataCamp Team

4 min

tutorial

Python IF, ELIF, and ELSE Statements

In this tutorial, you will learn exclusively about Python if else statements.
Sejal Jaiswal's photo

Sejal Jaiswal

9 min

tutorial

Conditionals and Control Flow in R Tutorial

Learn about relational operators for comparing R objects and logical operators for combining boolean TRUE and FALSE values. You'll also construct conditional statements.
Aditya Sharma's photo

Aditya Sharma

13 min

tutorial

Python String Contains

DataCamp Team's photo

DataCamp Team

5 min

See MoreSee More