Conditionals in Python: if, elif, else
A practical guide to Python conditionals — if, elif, else, truthiness, conditional expressions, and the patterns that keep branching logic clean and readable.
What you'll learn
- ✓How if, elif, and else direct control flow
- ✓What "truthy" and "falsy" really mean in Python
- ✓How to combine conditions cleanly
- ✓When to use a conditional expression instead of a full if/else
- ✓How to flatten deeply nested branches with early returns
Prerequisites
- •Comfortable with Python data types — see Data Types
- •Familiarity with variables — see Variables and Naming
Conditional statements decide which path your program takes. Almost every non-trivial program has at least one if, and as your programs grow, the way you structure branches is the single biggest lever on readability. This post covers Python’s conditional syntax in full, and then the habits that separate clean branching from a tangle of nested ifs.
The basic if statement
An if statement runs a block of code only when its condition is true:
temperature = 28
if temperature > 25:
print("It's warm today.")
The indented block runs only if the condition evaluates to True. Python uses indentation — not braces — to define the block. Four spaces is the convention.
If you want a fallback for the false case, add else:
temperature = 12
if temperature > 25:
print("It's warm today.")
else:
print("Bring a jacket.")
For more than two outcomes, chain elif (“else if”) branches between them:
score = 73
if score >= 90:
grade = "A"
elif score >= 80:
grade = "B"
elif score >= 70:
grade = "C"
elif score >= 60:
grade = "D"
else:
grade = "F"
print(grade) # C
Python evaluates each condition top to bottom and runs the first block whose condition is true. Everything after is skipped.
Truthy and falsy values
The condition in an if does not have to be a boolean. Python will convert any value to True or False using a simple rule: a handful of values are falsy, and everything else is truthy.
The falsy values are:
FalseNone0,0.0,0j- Empty containers:
"",[],(),{},set() - Custom objects whose
__bool__returnsFalse
Everything else — including non-empty strings, non-zero numbers, and non-empty containers — is truthy.
names = []
if names:
print("We have names.")
else:
print("List is empty.") # this runs
Prefer if names: over if len(names) > 0:. It is shorter, idiomatic, and just as clear once you have internalised the rule.
Combining conditions
Use and, or, and not to combine boolean expressions:
age = 22
has_ticket = True
if age >= 18 and has_ticket:
print("Welcome in.")
if age < 18 or not has_ticket:
print("Entry denied.")
A subtle but useful detail: and and or short-circuit. They stop evaluating as soon as the answer is known. This lets you guard against expensive or invalid operations:
data = None
if data is not None and len(data) > 0:
print(data[0])
If data is not None is false, len(data) is never evaluated — no TypeError.
Python also supports chained comparisons, which read like math:
score = 75
if 70 <= score < 80:
print("C grade")
This is exactly equivalent to score >= 70 and score < 80 but much easier to read.
Try it yourself. Write a small program that takes a year (e.g. year = 2024) and prints whether it is a leap year. A year is a leap year if it is divisible by 4, except for years divisible by 100, unless they are also divisible by 400.
Conditional expressions
When you want to choose one of two values based on a condition, a full if/else block is overkill. Python has a compact form sometimes called the ternary expression:
age = 17
status = "adult" if age >= 18 else "minor"
print(status) # minor
Read it as: “use 'adult' if the condition is true, otherwise 'minor'.” It is an expression, not a statement, so it returns a value you can assign or pass to a function.
Use conditional expressions for simple either/or value choices. If either branch needs more than one operation, use a regular if/else.
Comparing against multiple values
When you need to check whether a variable equals one of several values, do not write a long chain of == and or. Use in with a tuple or set:
day = "Saturday"
# Cluttered
if day == "Saturday" or day == "Sunday":
print("Weekend")
# Clean
if day in ("Saturday", "Sunday"):
print("Weekend")
For larger groups of values, prefer a set literal — membership checks are constant time:
vowels = {"a", "e", "i", "o", "u"}
letter = "e"
if letter in vowels:
print("Vowel")
match statements
Python 3.10 introduced match/case for situations where a long elif chain compares the same value:
def describe(status_code):
match status_code:
case 200:
return "OK"
case 301 | 302:
return "Redirect"
case 404:
return "Not Found"
case _:
return "Unknown"
print(describe(302)) # Redirect
case _ is the catch-all. match shines on structured data (tuples, dicts, dataclasses) where it can also unpack patterns — a topic for a later post. For simple integer or string dispatch, a dictionary lookup is often even cleaner; see Python Dictionaries for that pattern.
Avoiding deep nesting
Nested if statements are the most common source of unreadable Python. Two techniques flatten them out.
Early return. Inside a function, check failure cases first and return immediately:
# Nested
def discount(price, member):
if price > 0:
if member:
if price >= 100:
return price * 0.8
else:
return price * 0.9
return price
# Flat
def discount(price, member):
if price <= 0:
return price
if not member:
return price
if price >= 100:
return price * 0.8
return price * 0.9
The second version is easier to read because each condition is handled and dismissed before the next one begins.
Combine with and. Two nested checks that share a single outcome become one:
# Before
if user is not None:
if user.is_active:
send_email(user)
# After
if user is not None and user.is_active:
send_email(user)
Try it yourself. Refactor the following nested function to use early returns:
def can_vote(age, citizen, registered):
if age >= 18:
if citizen:
if registered:
return True
return FalseA worked example
Below is a small ticket-pricing function that uses most of what we have covered: chained elif, in, a chained comparison, and a conditional expression.
def ticket_price(age, day, is_member):
if day in ("Saturday", "Sunday"):
base = 20
else:
base = 15
if age < 12:
base = base * 0.5
elif 12 <= age < 18:
base = base * 0.75
elif age >= 65:
base = base * 0.7
final = base * 0.9 if is_member else base
return round(final, 2)
print(ticket_price(10, "Sunday", False)) # 10.0
print(ticket_price(30, "Monday", True)) # 13.5
print(ticket_price(70, "Saturday", True)) # 12.6
Notice that each step transforms a single base variable. The branches stay shallow because each block decides one thing.
Recap
You now know:
if,elif,elsedirect control flow based on a condition- Any value can be used as a condition — Python uses truthy/falsy rules
and,or, andnotcombine conditions, andand/orshort-circuit- Conditional expressions (
x if cond else y) are great for simple value choices - Use
into test against several values; prefer a set for large groups matchhandles structured cases cleanly in Python 3.10+- Flatten nested branches with early returns and combined conditions
Next steps
The next post is the natural companion to this one: a closer look at the operators that produce the conditions themselves. We will cover comparison operators, the difference between == and is, and the rules of boolean logic in detail.
→ Next: Comparison and Logical Operators in Python
Questions or feedback? Email codeloomdevv@gmail.com.