Combining Logical Operators

Introduction

Welcome back to Performing Operations on Python Data! Earlier, we introduced the Boolean type and the six comparison operators (==, !=, <, >, <=, >=) that turn yes-or-no questions into True or False values.

Real programs often need to ask questions that involve more than one condition at the same time. For example: "Is the person old enough and do they have a ticket?" or "Is the visitor a child or a senior?" To express these, Python gives us three logical operators: and, or, and not.

To keep things concrete, we will spend this lesson at the entrance of a concert venue, deciding who may enter and who pays full price. Here are our two starter variables:

age = 20
has_ticket = True

Think of age as a person's age in years and has_ticket as a Boolean flag saying whether they hold a valid ticket. Let's start combining conditions!

Combining Conditions with and

The and operator connects two Boolean expressions and returns True only when both sides are True. If even one side is False, the whole expression is False.

A good everyday picture is a secure door that needs both a keycard and a PIN. A valid keycard with the wrong PIN keeps the door shut. The right PIN with no keycard also keeps it shut. Only both together open it.

Our door at the venue works the same way: a guest must be at least 18 years old and hold a ticket. Let's store that decision in a well-named variable and report it:

# and: both sides must be True
can_enter = age >= 18 and has_ticket
print(f"Allowed to enter: {can_enter}")

Python evaluates each side first: age >= 18 becomes 20 >= 18, which is True, and has_ticket is already True. Since both sides are True, the whole expression is True, and that Boolean is saved into can_enter:

Allowed to enter: True

Notice the variable name. As we saw with comparisons, naming a Boolean after the question it answers (can_enter) makes the code read like plain English, and the f-string turns the result into a sentence a human would actually want to read.

Here is the complete behavior of and across all four possible combinations, with the keycard door as a guide:

LeftRightLeft and RightReading (keycard / PIN)
TrueTrueTrueBoth correct → door opens
TrueFalseFalseKeycard fine, PIN wrong → stays shut
FalseTrueFalseNo keycard, PIN fine → stays shut
FalseFalseFalseNeither → stays shut

Notice that only one row produces True. That is the essence of and: it is a strict operator that demands agreement from both sides.

Checking Alternatives with or

The or operator also connects two Boolean expressions, but the rule is more relaxed: the result is True when at least one side is True. It is only False when both sides are False.

Think of a discount offered to students or seniors. You do not need to be both; either qualification is enough to get the lower price.

Our venue offers exactly that kind of discount, for children under 13 or guests 65 and older:

# or: at least one side must be True
gets_discount = age < 13 or age >= 65
print(f"Gets a discount: {gets_discount}")

Python checks each side: age < 13 is 20 < 13, which is False, and age >= 65 is 20 >= 65, which is also False. Since neither side is True, the whole expression is False:

Gets a discount: False

Compare this table with the one for and; notice how or flips almost every row:

LeftRightLeft or RightReading (student / senior)
TrueTrueTrueBoth apply → discount
TrueFalseTrueStudent only → discount
FalseTrueTrueSenior only → discount
FalseFalseFalseNeither → full price

Flipping a Result with not

The not operator is a little different from and and or: it works on a single Boolean value and simply flips it. True becomes False, and False becomes True. There is no "left side" or "right side" here, just one expression to reverse.

You have met this idea online without noticing it. A website tracks whether you are logged in, and then shows the "Sign in" button when you are not logged in. One stored fact, one flipped reading of it.

At our venue, the guests who need to buy a ticket are exactly the ones who do not already have one:

# not: flips True to False and back
print(f"Needs to buy a ticket: {not has_ticket}")

Since has_ticket is True, not has_ticket becomes False:

Needs to buy a ticket: False

A handy way to read not is as the word "isn't" or "doesn't" in English. The expression not has_ticket reads as "the person doesn't have a ticket," which is a natural way to phrase the opposite question. Reach for not whenever it makes your condition read more clearly than rewriting the comparison itself.

Combining Logical Operators in One Expression

We can freely mix and, or, and not in the same expression to build richer conditions. At our venue, full price applies to adults who are not over 65:

# Combining operators in one condition
full_price = age >= 18 and not (age > 65)
print(f"Pays full price: {full_price}")

Python follows a fixed precedence order: parentheses first, then comparisons such as age > 65, then not, then and, then or. Let's trace through the expression step by step:

  1. Inside the parentheses, age > 65 is 20 > 65, which is False.
  2. not (False) flips it to True.
  3. age >= 18 is 20 >= 18, which is True.
  4. Finally, True and True evaluates to True.
Pays full price: True

Even though Python knows the precedence rules by heart, adding parentheses (like around age > 65) makes the intent obvious to any human reading the code. When in doubt, wrap it: clarity beats cleverness.

Changing the inputs and re-running

Just as with the formula problems earlier in this course, the real payoff of storing our inputs in variables is that we can test a completely different guest without touching the logic. Let's send a 10-year-old with no ticket to the door:

age = 10           # was 20
has_ticket = False # was True

can_enter = age >= 18 and has_ticket
gets_discount = age < 13 or age >= 65

print(f"Allowed to enter: {can_enter}")
print(f"Gets a discount: {gets_discount}")

Only the two input lines changed, yet both answers flip:

Allowed to enter: False
Gets a discount: True

Look closely at why each one changed. For can_enter, both sides are now False, and and needs both to be True, so the door stays shut. For gets_discount, age < 13 is now True, and or only needs one True, so the discount applies. This is the difference between and and or in a single glance — far more memorable than reading it off a table. Try a few more guests yourself: a 70-year-old with a ticket, or a 30-year-old without one.

Conclusion and Next Steps

Great job! You have added three powerful logical operators to your toolbox: and (both sides must be True), or (at least one side must be True), and not (flips a single Boolean). You also saw how naming the result (can_enter, gets_discount, full_price) and printing it with an f-string turns a bare True into a real answer, and how changing the inputs reveals each operator's personality.

This also wraps up Performing Operations on Python Data! We journeyed from arithmetic operators and precedence, through string building with concatenation and f-strings, to solving formula problems, then comparisons, and now these logical combinators.

Right now, our programs can work out whether a guest may enter, but they still print the answer either way. Next, in Making Decisions in Python, we will learn to say "if can_enter is True, print the welcome message, otherwise send them to the ticket desk" — the point where these conditions finally start steering the program. Before that, a fresh set of practices is ready for you. Time to combine some conditions and watch your Booleans in action!

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal