Python - If/Elif/Else Statement
Every useful program makes decisions. Should we grant access to this user? Is this input valid? Does this order qualify for free shipping? Conditional statements are how you encode these decisions in...
Key Insights
- Conditional statements are the decision-making backbone of every Python program—master them first, and everything else becomes easier to understand.
- The order of your
elifconditions matters significantly; Python evaluates them top-to-bottom and stops at the first match. - Deep nesting is a code smell; use guard clauses and combined conditions to write flatter, more readable code.
Introduction to Conditional Logic
Every useful program makes decisions. Should we grant access to this user? Is this input valid? Does this order qualify for free shipping? Conditional statements are how you encode these decisions in code.
At its core, a conditional statement evaluates an expression to either True or False, then executes different code paths based on the result. This is fundamental flow control—the ability to branch your program’s execution based on runtime conditions.
Think of it like checking if a door is locked before deciding your next action:
door_locked = True
if door_locked:
print("Use your key to unlock the door")
print("Then enter the house")
else:
print("Walk right in")
This simple pattern—check a condition, do one thing or another—scales up to handle complex business logic, validation rules, and state management. Let’s break down each component.
The if Statement
The if statement is the foundation. It evaluates a boolean expression and executes its code block only when that expression is True.
if condition:
# This code runs only when condition is True
do_something()
Notice the colon after the condition and the indentation of the code block. Python uses indentation (typically 4 spaces) to define code blocks rather than braces. This isn’t optional—it’s part of the syntax.
Here’s a practical example checking if a number is positive:
temperature = 25
if temperature > 0:
print(f"Temperature is {temperature}°C (above freezing)")
print("No risk of ice on the roads")
Python evaluates temperature > 0, which returns True since 25 is greater than 0. Both print statements execute.
Understanding Truthiness
Python doesn’t require explicit boolean values. It evaluates the “truthiness” of any expression:
user_input = "hello"
if user_input: # Non-empty strings are truthy
print("User provided input")
items = []
if items: # Empty lists are falsy
print("This won't print")
Falsy values include: False, None, 0, 0.0, "" (empty string), [] (empty list), {} (empty dict), and set(). Everything else is truthy.
This is useful but can be a source of bugs. Be explicit when clarity matters:
# Ambiguous: does this check for None or zero?
if value:
process(value)
# Explicit: clearly checking for None
if value is not None:
process(value)
Adding Alternatives with else
The else clause provides a fallback when the if condition is False:
password = "secret123"
user_input = "wrongpassword"
if user_input == password:
print("Login successful")
print("Redirecting to dashboard...")
else:
print("Invalid password")
print("Please try again")
The else block has no condition—it catches everything that didn’t match the if. You can only have one else, and it must come last.
A common pattern is validation before processing:
def process_order(quantity):
if quantity > 0:
total = quantity * 29.99
print(f"Order placed: {quantity} items, total ${total:.2f}")
else:
print("Error: Quantity must be positive")
Multiple Conditions with elif
When you have more than two possible outcomes, elif (short for “else if”) lets you chain conditions:
def get_letter_grade(score):
if score >= 90:
return "A"
elif score >= 80:
return "B"
elif score >= 70:
return "C"
elif score >= 60:
return "D"
else:
return "F"
print(get_letter_grade(85)) # Output: B
print(get_letter_grade(72)) # Output: C
print(get_letter_grade(45)) # Output: F
Python evaluates conditions from top to bottom and executes only the first matching block. This is critical—order matters.
Consider what happens if we reverse the order:
# WRONG: This always returns "F" for passing scores
def broken_grade(score):
if score >= 60:
return "D" # 85 is >= 60, so this matches first!
elif score >= 70:
return "C" # Never reached for scores >= 60
elif score >= 80:
return "B" # Never reached
elif score >= 90:
return "A" # Never reached
else:
return "F"
Always order your conditions from most specific to least specific, or from highest threshold to lowest when dealing with ranges.
Combining Conditions
Real-world logic often requires checking multiple conditions simultaneously. Python provides and, or, and not operators for this.
Using and
Both conditions must be True:
age = 25
has_membership = True
if age >= 18 and has_membership:
print("Access granted to premium content")
else:
print("Access denied")
Using or
At least one condition must be True:
is_admin = False
is_moderator = True
if is_admin or is_moderator:
print("You can edit this post")
Using not
Inverts the boolean value:
maintenance_mode = False
if not maintenance_mode:
print("System is operational")
Complex Conditions
You can combine these operators. Use parentheses for clarity:
def can_access_feature(user):
age = user.get("age", 0)
is_premium = user.get("is_premium", False)
is_admin = user.get("is_admin", False)
# Admins always have access, or premium users 18+
if is_admin or (is_premium and age >= 18):
return True
else:
return False
Nested vs. Combined Conditions
You could write nested conditionals instead:
# Nested approach - harder to read
if is_admin:
return True
else:
if is_premium:
if age >= 18:
return True
return False
The combined approach is almost always cleaner. Nested conditionals should be a last resort when the logic truly requires different handling at each level.
Common Patterns and Best Practices
Avoid Deep Nesting
Deeply nested conditionals are hard to read and maintain:
# Hard to follow
def process_payment(user, amount):
if user is not None:
if user.is_active:
if amount > 0:
if user.balance >= amount:
user.balance -= amount
return "Payment successful"
else:
return "Insufficient funds"
else:
return "Invalid amount"
else:
return "Account inactive"
else:
return "User not found"
Use Guard Clauses
Guard clauses check for invalid conditions early and return immediately:
# Much cleaner
def process_payment(user, amount):
if user is None:
return "User not found"
if not user.is_active:
return "Account inactive"
if amount <= 0:
return "Invalid amount"
if user.balance < amount:
return "Insufficient funds"
user.balance -= amount
return "Payment successful"
The logic flows linearly. Each guard clause handles one error case, and the happy path is at the end, unindented.
Ternary Expressions for Simple Cases
For simple if/else assignments, Python offers a one-line ternary expression:
# Instead of this:
if score >= 60:
status = "Pass"
else:
status = "Fail"
# Write this:
status = "Pass" if score >= 60 else "Fail"
Use this sparingly. If your ternary expression is hard to read at a glance, use the full if/else.
Avoid Redundant Conditions
Don’t compare booleans to True or False:
# Redundant
if is_valid == True:
process()
# Clean
if is_valid:
process()
# Redundant
if has_error == False:
continue_processing()
# Clean
if not has_error:
continue_processing()
Conclusion
The if/elif/else statement is deceptively simple but forms the backbone of program logic. Master these principles:
- Use
iffor single conditions - Add
elsewhen you need a fallback - Chain
eliffor multiple exclusive conditions, ordered from most to least specific - Combine conditions with
and,or, andnotinstead of nesting - Use guard clauses to keep your code flat and readable
Once you’re comfortable with these patterns, explore Python’s match statement (introduced in Python 3.10) for more complex pattern matching, and learn how conditionals interact with loops for iteration control. But get the fundamentals right first—clean conditional logic is the foundation of maintainable code.