Conditional Statements: if, elif and else
Conditions choose which block runs. Python adds chained comparisons, truthiness and a conditional expression that together remove most of the nesting other languages need.
- The if statement
- if and else
- elif
- elif is not the same as several ifs
- Conditions do not have to be booleans
- Chained and combined conditions
- Nested conditions, and how to avoid them
- The conditional expression
- Matching against many values
- With a dictionary
- With match, from Python 3.10
- The pass statement
- Common mistakes
- Best practices
- Practice
- Conclusion
- Basics
- Data Types
- Operators
- Strings
- Control Flow
- Lists
- Tuples
- Sets
- Dictionaries
- Comprehensions
- Functions
- Advanced Functions
- Recursion
- Exception Handling
- File Handling
- Modules
- Standard Library
- OOP
- Advanced OOP
- Iterators and Generators
- Decorators
- Context Managers
- Descriptors and Dataclasses
- Python Internals
- Concurrency
- Regular Expressions
- Serialization
- Command Line Python
- Testing and Debugging
- Type Hints
- Performance
- Python Security
- DSA with Python
The if statement
age = 20
if age >= 18:
print("Adult")
print("May vote")
print("Always runs")The colon opens the block and the indentation defines it. Both indented lines belong to the if; the unindented line does not. There are no braces and no then keyword.
if and else
temperature = 15
if temperature > 30:
print("Hot")
else:
print("Not hot")elif
elif is short for "else if". Only the first matching branch runs, and the rest are skipped entirely.
score = 78
if score >= 90:
grade = "A"
elif score >= 80:
grade = "B"
elif score >= 70:
grade = "C"
elif score >= 40:
grade = "D"
else:
grade = "F"
print(grade) # COrder matters. Because only the first true branch runs, the tests must run from the most specific to the least. Reversing this ladder so it starts with score >= 40 would give every passing student a D.elif is not the same as several ifs
n = 15
# One branch runs.
if n > 10:
print("greater than 10")
elif n > 5:
print("greater than 5")
# BOTH run, because each if is evaluated independently.
if n > 10:
print("greater than 10")
if n > 5:
print("greater than 5")Conditions do not have to be booleans
items = []
name = ""
count = 0
if not items:
print("no items")
if name:
print("named")
else:
print("no name given")
if count:
print("has a count") # does not run; 0 is falsyAny object can be tested. Use this for emptiness, and use is None when absence must be distinguished from zero or empty.
Chained and combined conditions
age = 25
has_licence = True
if 18 <= age < 65:
print("working age")
if age >= 18 and has_licence:
print("may drive")
if age < 5 or age > 90:
print("special rate")
day = "sat"
if day in ("sat", "sun"): # far better than day == "sat" or day == "sun"
print("weekend")Nested conditions, and how to avoid them
# Deeply nested: hard to follow
def process(order):
if order is not None:
if order.get("paid"):
if order.get("items"):
return "ready to ship"
else:
return "no items"
else:
return "unpaid"
else:
return "no order"# Guard clauses: each failure exits immediately, the happy path stays flat
def process(order):
if order is None:
return "no order"
if not order.get("paid"):
return "unpaid"
if not order.get("items"):
return "no items"
return "ready to ship"The second version says the same thing with no nesting at all. Handling failures first and returning early is the single most effective way to keep Python functions readable.
The conditional expression
age = 20
# Statement form
if age >= 18:
label = "adult"
else:
label = "minor"
# Expression form: the whole thing produces a value
label = "adult" if age >= 18 else "minor"
print(f"You are an {label}" if age >= 18 else f"You are a {label}")
# Useful inside a call or a comprehension
scores = [45, 82, 91, 30]
print([("pass" if s >= 50 else "fail") for s in scores])Keep it to one line and one condition. Nesting conditional expressions inside each other is legal and unreadable; use elif instead.
Matching against many values
With a dictionary
def describe_day(code):
names = {1: "Monday", 2: "Tuesday", 3: "Wednesday"}
return names.get(code, "Unknown")
print(describe_day(2)) # Tuesday
print(describe_day(9)) # UnknownA dictionary lookup replaces a long elif ladder that tests one variable against constants, and it is easier to extend.
With match, from Python 3.10
def handle(command):
match command.split():
case ["quit"]:
return "exiting"
case ["add", item]:
return f"adding {item}"
case ["move", x, y]:
return f"moving to {x},{y}"
case _:
return "unknown command"
print(handle("add pen")) # adding pen
print(handle("move 3 4")) # moving to 3,4
print(handle("dance")) # unknown commandmatch is structural pattern matching, not a C style switch. It destructures the value as well as comparing it, which is where its real value lies. The final case _ is the catch all.
The pass statement
if some_condition:
pass # deliberately do nothing, for now
else:
handle_it()A block cannot be empty. pass is the placeholder that keeps the code parseable while you write the rest.
Common mistakes
- Forgetting the colon at the end of the
if,eliforelseline. - Using
=instead of==in a condition. Python raises aSyntaxError, which is helpful. - Writing
if x == 1 or 2:. The2is a separate truthy operand, so the whole condition is always true. Writeif x in (1, 2):. - Ordering an
elifladder from least specific to most specific. - Writing
if x == True:instead ofif x:. - Using truthiness where
0is valid data andis Nonewas needed.
Best practices
- Use guard clauses and early returns instead of nesting.
- Use
inwith a tuple or a set instead of a chain oforcomparisons. - Give a complicated condition a name:
is_eligible = age >= 18 and has_licence. - Replace an
elifladder that maps one value to another with a dictionary. - Keep conditional expressions short and standalone.
Practice
- Write a grade classifier and then deliberately reverse the ladder order. Explain what breaks.
- Rewrite a triple nested validation function using guard clauses.
- Write a leap year check using
and,orand%, and test 1900, 2000, 2024 and 2025. - Convert an
elifladder that maps month numbers to names into a dictionary lookup. - Explain why
if name == "a" or "b":is always true, and rewrite it.
Conclusion
if, elif and else are simple; keeping them readable is the skill. Return early, name your conditions, use in for value sets, and let a dictionary do the work when you are mapping one value to another.