Python lesson 4 of 9
Python Conditionals: if, elif, and else
Learn how Python decides what to run using if, elif, and else, plus comparison operators, and/or/not, truthiness, and the conditional expression.
Published · Every example on this page was run before it was published.
Every program you have written so far runs straight through from the first line to the last, doing the exact same thing every time. Real programs are not like that. A login screen shows a welcome message or an error message. A shopping cart applies a discount only when the total is big enough. A game ends only when your health reaches zero. To write programs like those you need a way to say "run this part only when something is true," and in Python that tool is the conditional statement.
What a Condition Is
A condition is any expression that Python can boil down to one of two values: True or False. Those
two values are called booleans (named after the mathematician George Boole), and they are a real
Python type just like numbers and strings are. You can store them in variables, print them, and combine
them.
Think of a condition as a yes-or-no question asked about your data. A bouncer at a club door asks one
question — "is this person eighteen or older?" — and the answer is always yes or no, never "maybe" or
"sort of." Depending on the answer the bouncer takes one of two actions. Python works the same way: it
evaluates the question, gets True or False, and picks a path.
The most common way to build a condition is with a comparison operator, which compares two values and produces a boolean:
| Operator | Question it asks |
| --- | --- |
| == | Are these two values equal? |
| != | Are these two values different? |
| > | Is the left value greater than the right? |
| < | Is the left value less than the right? |
| >= | Is the left value greater than or equal to the right? |
| <= | Is the left value less than or equal to the right? |
Notice that equality is spelled with two equals signs. A single = means "store this value in this
variable," which is a completely different job. Mixing them up is the single most common beginner error
with conditionals, and we come back to it at the end of the lesson.
Comparisons work on their own, outside of any if statement. You can print them to see the boolean that
comes out:
age = 20
print(age > 18)
print(age == 20)
print(age != 20)
print(3 + 4 >= 10)
print("cat" == "Cat")True
True
False
False
FalseThat last line matters: string comparison in Python is case-sensitive, so "cat" and "Cat" are
different values. Note also that Python evaluates the arithmetic 3 + 4 first and only then compares the
result 7 against 10, which is why the answer is False.
Writing if, elif, and else
An if statement takes a condition and a block of code. If the condition is True, the block runs. If
it is False, Python skips the whole block and carries on with the rest of the program.
temperature = 31
if temperature > 28:
print("It is hot today.")
print("Remember to drink water.")
print("Have a good day.")It is hot today.
Remember to drink water.
Have a good day.Look closely at the shape of that code. The line starting with if ends in a colon, and the two lines
that belong to it are pushed in from the left margin. That push-in is called indentation, and in
Python it is not decoration — it is the actual grammar of the language. Many other languages wrap
conditional blocks in curly braces and treat indentation as a style choice. Python has no braces, so the
indentation itself is what tells the interpreter "these lines belong to the if." The final print line
sits back at the left margin, so it is outside the block and runs no matter what.
The standard is four spaces per level of indentation, and you must be consistent inside a single block. Every line in one block needs the same indentation, and mixing tab characters with spaces will make Python complain even when the code looks perfectly aligned on your screen.
To handle the false case, add an else block. It has no condition of its own — it simply catches
everything the if did not:
password = "hunter2"
if len(password) >= 8:
print("Password accepted.")
else:
print("Password is too short.")Password is too short.The string "hunter2" has seven characters, so len(password) >= 8 is False and the else block
runs. Exactly one of the two blocks runs — never both, never neither.
When you have more than two possible outcomes, use elif, which is short for "else if." You can chain as
many elif blocks as you need between the opening if and the optional closing else:
score = 83
if score >= 90:
grade = "A"
elif score >= 80:
grade = "B"
elif score >= 70:
grade = "C"
else:
grade = "F"
print("Your grade is", grade)Your grade is BPython checks the conditions strictly from top to bottom and stops at the first one that is True.
It never looks at the rest. That is why order matters enormously in an elif chain. Here is the same
idea with the conditions written in the wrong order:
score = 95
if score >= 70:
print("C")
elif score >= 80:
print("B")
elif score >= 90:
print("A")CA score of 95 really is greater than or equal to 70, so the very first branch wins and the better branches below are never reached. The fix is to put the most demanding condition first. When you build a chain of ranges, always read it from the top and ask whether an earlier branch could swallow a case meant for a later one.
Combining Conditions with and, or, not
Real decisions usually depend on more than one fact. Python gives you three logical operators to build compound conditions out of simpler ones:
andproducesTrueonly when the conditions on both sides are true.orproducesTruewhen at least one side is true.notflips a single boolean to its opposite.
day = "Saturday"
weather = "sunny"
if day == "Saturday" and weather == "sunny":
print("Perfect beach day.")
if day == "Saturday" or day == "Sunday":
print("It is the weekend.")
if not weather == "rainy":
print("No umbrella needed.")Perfect beach day.
It is the weekend.
No umbrella needed.That third condition works, but if weather != "rainy": says the same thing more directly, and clearer
code is better code. Save not for cases where the thing you are flipping is already a boolean, such as
if not is_logged_in:.
These operators also have an important safety feature called short-circuiting. With and, if the
left side is already False, Python does not even evaluate the right side — the overall answer cannot
change. That lets you guard a risky operation behind a cheap check:
items = []
if items and items[0] == "apple":
print("The first item is an apple.")
else:
print("No apple at the front.")No apple at the front.An empty list has no position 0, so items[0] on its own would crash the program with an IndexError.
Because the left side of the and is false for an empty list, Python never runs items[0] at all. Put
your guard on the left and the thing that needs guarding on the right.
Truthiness: What Python Treats as False
The condition in an if statement does not have to be an actual boolean. Python will accept any value
and decide for itself whether that value counts as true or false. This behaviour is nicknamed
truthiness, and the values that count as false are called falsy.
The falsy values you will meet as a beginner are short and worth memorising:
- the number
0(and0.0) - the empty string
"" - the empty list
[] - the empty dictionary
{}and the empty tuple() None, Python's word for "no value at all"
Everything else — any non-zero number, any string with at least one character, any list with at least
one item — is truthy. The built-in bool() function shows you exactly how Python judges a value:
print(bool(0))
print(bool(42))
print(bool(""))
print(bool("hi"))
print(bool([]))
print(bool([1, 2]))
print(bool(None))False
True
False
True
False
True
FalseThis is why the idiomatic way to ask "does this list have anything in it?" is simply to put the list in the condition:
cart = []
if cart:
print("Your cart has", len(cart), "items.")
else:
print("Your cart is empty.")Your cart is empty.Truthiness makes code short and readable when you genuinely mean "is this empty or missing?" It becomes a bug when zero is a meaningful value in your data, because Python cannot tell the difference between "the number zero" and "nothing was supplied." We will see exactly that trap in the Common Mistakes section.
Nesting Versus Flattening with elif
You can put an if statement inside another if statement, indenting it one more level. This is called
nesting, and it is the right tool when the second question only makes sense after the first one has
been answered:
username = "ada"
password = "secret123"
if username == "ada":
if password == "secret123":
print("Welcome back, Ada.")
else:
print("Wrong password.")
else:
print("Unknown user.")Welcome back, Ada.Asking about the password only makes sense once you know the user exists, so nesting reads naturally here. But nesting is often used where it is not needed, and each extra level pushes your code further right and makes it harder to follow. Here is a classification written with three levels of nesting:
n = 7
if n < 0:
print("negative")
else:
if n == 0:
print("zero")
else:
if n < 10:
print("small")
else:
print("large")smallEvery one of those questions is asked about the same value, and only one answer can ever apply. That is
precisely the situation elif exists for:
n = 7
if n < 0:
print("negative")
elif n == 0:
print("zero")
elif n < 10:
print("small")
else:
print("large")smallSame result, half the indentation, and the four possible outcomes now line up in a column you can read
at a glance. A good rule of thumb: if every nested if is testing the same variable, flatten the whole
thing into one elif chain.
The Conditional Expression
Sometimes you only want to choose between two values, not two blocks of code. Writing a four-line
if/else just to set one variable feels heavy, so Python offers a one-line form called a conditional
expression (many programmers call it the ternary operator). It reads almost like English:
value_if_true if condition else value_if_false
count = 1
label = "item" if count == 1 else "items"
print(count, label)
count = 4
label = "item" if count == 1 else "items"
print(count, label)1 item
4 itemsThe condition in the middle is evaluated first; if it is True the whole expression becomes the value
on the left, and otherwise it becomes the value on the right. Because it is an expression rather than a
statement, you can use it anywhere a value is allowed — inside a print() call, inside a list, or on the
right-hand side of an assignment as above.
Keep it for short, simple choices. If either branch needs more than a brief value, or if you find
yourself nesting one conditional expression inside another, go back to a regular if/else block; the
extra lines buy real readability.
A Worked Example
This short program reviews a week of temperature readings, labels each one, counts the extremes, and
finishes with a summary. It pulls together comparisons, an elif chain, a counter, and a conditional
expression.
readings = [18, 31, 0, -4, 25, 40]
hot_days = 0
cold_days = 0
for reading in readings:
if reading >= 30:
status = "hot"
hot_days = hot_days + 1
elif reading <= 0:
status = "cold"
cold_days = cold_days + 1
else:
status = "mild"
print(reading, "->", status)
print("Hot days:", hot_days)
print("Cold days:", cold_days)
alert = "heat warning" if hot_days >= 2 else "no warning"
print("Status:", alert)18 -> mild
31 -> hot
0 -> cold
-4 -> cold
25 -> mild
40 -> hot
Hot days: 2
Cold days: 2
Status: heat warningHere is what each part does. Line 1 stores the week's readings in a list, and lines 2 and 3 create two counter variables starting at zero — variables whose only job is to keep a running tally.
The for loop walks through the list one value at a time, and on each pass the variable reading holds
the current value. Everything indented under the for line runs once per reading.
Inside the loop sits an elif chain. Python first asks whether the reading is at least 30. If so, it
labels the day "hot" and adds one to hot_days. Only if that first question is False does Python ask
the second one, whether the reading is zero or below. If both fail, the else block labels the day
"mild". Exactly one of the three branches runs for each reading, so no day is ever counted twice.
The print on the last line of the loop body is indented to the loop's level but not to the if
level, so it runs after whichever branch was chosen — that is indentation doing real work.
Notice the reading of 0. It is correctly labelled cold because the condition asks reading <= 0
explicitly. Had the code tried to use truthiness with something like if not reading:, the zero would
have been treated as "no reading at all" rather than as a freezing day, which is exactly the kind of bug
truthiness invites when zero is legitimate data.
After the loop finishes, the two print calls at the left margin report the totals. Finally the
conditional expression picks one of two strings based on hot_days. Since two days hit 30 degrees or
more, the condition hot_days >= 2 is True and alert becomes "heat warning".
Common Mistakes
1. Using = where == belongs. Assignment and comparison look similar and mean opposite things. The
condition below is not a question at all, it is an attempt to store a value:
x = 5
if x = 5:
print("five")Python refuses to run this and reports a SyntaxError. That is actually good news — the language catches
the mistake for you instead of letting it hide. Read == out loud as "is equal to" and = as "gets," and
the two stop blurring together:
x = 5
if x == 5:
print("five")five2. Expecting or to spread across a comparison. In English "if the grade is A or B" is perfectly
clear, so beginners write it the same way in Python. Python reads it very differently:
grade = "C"
if grade == "A" or "B":
print("Great job!")
else:
print("Keep practicing.")Great job!Python sees two entirely separate conditions joined by or: first grade == "A", which is False, and
then the bare string "B", which is a non-empty string and therefore truthy. False or True is True,
so the congratulation prints for a grade of C. Spell out the second comparison in full:
grade = "C"
if grade == "A" or grade == "B":
print("Great job!")
else:
print("Keep practicing.")Keep practicing.For a longer list of options, if grade in ("A", "B", "C"): is shorter and reads well. And while we are
on the subject of comparisons that trip people up: Python genuinely supports chained comparisons, so
0 <= n <= 35 is valid and means exactly what it looks like — n is at least 0 and at most 35. Most
languages do not allow that, which cuts both ways. If you come from one of them you may write it out the
long way unnecessarily, and if you rely on the chain in Python you should remember it only works for
comparison operators, never as a way to chain or around a single value.
3. Leaning on truthiness when you mean "is missing." Suppose a discount is either a number or None
when the customer supplied nothing:
discount = 0
if not discount:
print("No discount was supplied.")
else:
print("Discount is", discount)No discount was supplied.A discount of zero is a real answer, but 0 is falsy, so the program reports it as missing. Ask the
precise question instead. is None checks whether the value is literally Python's None object, and
nothing else can accidentally match it:
discount = 0
if discount is None:
print("No discount was supplied.")
else:
print("Discount is", discount)Discount is 0Use bare truthiness when "empty" and "missing" should genuinely be treated the same way, and is None
whenever zero, an empty string, or an empty list could be meaningful data. Note that it is is None, not
== None — is asks whether two names refer to the very same object, which is the right question for a
one-of-a-kind value like None.
4. Getting the indentation wrong. Because indentation defines the block, a line in the wrong column changes the meaning of your program or stops it running entirely:
if score > 50:
print("You passed.")Python expects an indented block after the colon and raises an IndentationError when it does not find
one. The opposite version is sneakier, because it runs:
score = 20
if score > 50:
print("You passed.")
print("Great work!")Great work!The congratulation was meant to belong to the if, but it sits at the left margin, so it prints for a
failing score too. Nothing errors — the program is simply wrong. Whenever a message appears when it
should not, check the column it starts in before you check anything else.
Next Steps
Try the linked practice problem, balanced-parentheses. It asks you to scan through a string and
decide whether every opening bracket has a matching closing one, which means making a decision about
every single character — if for an opener, elif for a closer, and a careful check for the mismatch
case. It is an excellent exercise in getting an elif chain in the right order.
Before that, open the Python playground and experiment. Change the values in the
grading chain and confirm you can predict the branch that runs. Print bool() of a few odd values, such
as bool(" ") and bool("0"), and see whether the results surprise you. Getting a feel for which
conditions are true is the fastest route to writing them confidently.
Write it yourself
Reading about code and writing it are different skills. These exercises practise exactly what this lesson covered; they run in this tab and need no account.
When you want a harder one
Interview-style problems graded against hidden tests — a big step up from the exercises. Come back to these when the ideas in this lesson feel comfortable rather than new.