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:
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:
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:
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:
| Left | Right | Left and Right | Reading (keycard / PIN) |
|---|---|---|---|
True | True | True | Both correct → door opens |
True | False | False | Keycard fine, PIN wrong → stays shut |
False | True | False | No keycard, PIN fine → stays shut |
False | False | False | Neither → 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:
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:
Compare this table with the one for and; notice how or flips almost every row:
| Left | Right | Left or Right | Reading (student / senior) |
|---|---|---|---|
True | True | True | Both apply → discount |
True | False | True | Student only → discount |
False | True | True | Senior only → discount |
False | False | False | Neither → 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:
Since has_ticket is True, not has_ticket becomes 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:
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:
- Inside the parentheses,
age > 65is20 > 65, which isFalse. not (False)flips it toTrue.age >= 18is20 >= 18, which isTrue.- Finally,
True and Trueevaluates toTrue.
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:
Only the two input lines changed, yet both answers flip:
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!
