Python Conditional Statements: The Complete Beginner's Guide
Every useful program makes decisions. This chapter turns comparisons and booleans into real branching logic with \`if/elif/else\`, readable guard clauses, nested conditions, ternary expressions, and \`match\` for Python 3.10+ multi-branch flows.
Chapter 8 of 20 · Beginner · 40 min · Python Programming Course
Every useful program makes decisions. Show this page if the user is logged in. Charge this price if the customer has a premium account. Send the alert if the temperature exceeds the threshold. Approve the loan if income is above the minimum and age is over eighteen.
Decision-making in Python is handled by conditional statements — code that evaluates a condition and executes different instructions depending on whether that condition is True or False.
You already have everything you need to write powerful conditions: comparison operators from Day 3, boolean values from Day 2, and rich data from the dictionaries, lists, and sets you built in Days 5 through 7. This chapter puts all of it together into programs that actually think.
What You Will Learn in This Chapter
By the end of this tutorial you will be able to:
- Write
if,elif, andelsestatements correctly - Combine multiple conditions using
and,or, andnot - Write nested conditionals for multi-level decisions
- Use ternary expressions for clean one-line conditionals
- Apply truthy and falsy evaluation to write concise conditions
- Use match statements for clean multi-branch logic (Python 3.10+)
- Recognise and fix the most common conditional mistakes
- Write conditions that are readable, not just correct
Estimated time: 40 minutes reading + 20 minutes practice
The if Statement — The Foundation of Every Decision
An if statement evaluates a condition. If the condition is True, the indented block runs. If it is False, Python skips it entirely:
temperature = 38
if temperature > 35:
print("It is very hot today")
print("Stay hydrated")
print("This always runs")
Output:
It is very hot today
Stay hydrated
This always runs
Two things to notice immediately:
- The colon after the condition is required.
if temperature > 35:— forgetting the colon is aSyntaxError. - Indentation defines the block. Everything indented under the
ifis part of its block. The moment indentation returns to the original level, the block ends. Python does not use curly braces like C++ or Java — indentation is the syntax.
score = 45
if score >= 50:
print("Passed") # only runs if score >= 50
print("Well done") # also only runs if score >= 50
print("Exam complete") # always runs — outside the if block
if/else — Handling Both Outcomes
else provides a block that runs when the if condition is False:
age = 16
if age >= 18:
print("You can vote")
else:
print("You cannot vote yet")
Output:
You cannot vote yet
Exactly one of the two blocks will run — never both, never neither. This is guaranteed.
balance = 1200
withdrawal = 1500
if withdrawal <= balance:
balance -= withdrawal
print(f"Withdrawal successful. New balance: {balance}")
else:
print(f"Insufficient funds. Balance: {balance}, Requested: {withdrawal}")
Output:
Insufficient funds. Balance: 1200, Requested: 1500
elif — Multiple Branches
elif (short for "else if") lets you check multiple conditions in sequence. Python evaluates them top to bottom and executes the first block whose condition is True. All remaining branches are skipped:
score = 83
if score >= 90:
grade = "A"
elif score >= 80:
grade = "B"
elif score >= 70:
grade = "C"
elif score >= 60:
grade = "D"
else:
grade = "F"
print(f"Score: {score} → Grade: {grade}")
Output:
Score: 83 → Grade: B
Python checked score >= 90 (False), then score >= 80 (True) — found a match, ran that block, and skipped all the remaining elif and else branches.
The Order of elif Matters
Conditions are checked sequentially. If an earlier condition is too broad, it catches cases that should have fallen through to a later branch:
score = 95
# Wrong order — first condition catches everything >= 60
if score >= 60:
grade = "D" # score 95 lands here — wrong
elif score >= 70:
grade = "C"
elif score >= 80:
grade = "B"
elif score >= 90:
grade = "A"
print(grade) # D — incorrect
# Correct order — most restrictive condition first
if score >= 90:
grade = "A" # score 95 correctly lands here
elif score >= 80:
grade = "B"
elif score >= 70:
grade = "C"
elif score >= 60:
grade = "D"
else:
grade = "F"
print(grade) # A — correct
Rule: when conditions overlap, put the most restrictive (most specific) condition first.
Combining Conditions With and, or, not
You covered logical operators in Day 3. Here is how they appear in real conditional statements.
and — Both Conditions Must Be True
age = 25
has_licence = True
has_insurance = True
if age >= 18 and has_licence and has_insurance:
print("You can drive")
else:
print("You cannot drive")
# Output: You can drive
temperature = 28
humidity = 55
if temperature >= 20 and temperature <= 30 and humidity < 70:
print("Perfect weather for outdoor exercise")
else:
print("Consider indoor exercise today")
# Output: Perfect weather for outdoor exercise
or — At Least One Condition Must Be True
day = "Saturday"
if day == "Saturday" or day == "Sunday":
print("Weekend — no work")
else:
print("Weekday — work day")
# Output: Weekend — no work
user_role = "moderator"
if user_role == "admin" or user_role == "moderator":
print("You can delete posts")
else:
print("You cannot delete posts")
not — Reverses the Boolean
is_logged_in = False
if not is_logged_in:
print("Please log in to continue")
# Output: Please log in to continue
banned_users = {"troll_99", "spammer_42"}
username = "alice"
if username not in banned_users:
print(f"Welcome, {username}")
else:
print("Access denied")
# Output: Welcome, alice
Combining All Three
age = 22
has_ticket = True
is_banned = False
if age >= 18 and has_ticket and not is_banned:
print("Entry granted")
else:
print("Entry denied")
# Output: Entry granted
Use parentheses to make complex conditions explicit:
# Ambiguous — what groups together?
if a > 0 and b > 0 or c > 0:
pass
# Clear — intent is obvious
if (a > 0 and b > 0) or c > 0:
pass
Nested Conditionals — Decisions Inside Decisions
A nested conditional is an if statement inside another if block. Use this when the inner decision only makes sense after the outer condition is confirmed:
user_type = "premium"
purchase_amount = 150
if user_type == "premium":
if purchase_amount >= 100:
discount = 0.20
print(f"Premium + large order: 20% discount")
else:
discount = 0.10
print(f"Premium + small order: 10% discount")
else:
if purchase_amount >= 100:
discount = 0.05
print(f"Standard + large order: 5% discount")
else:
discount = 0.00
print(f"Standard + small order: no discount")
print(f"Final discount: {discount * 100:.0f}%")
Output:
Premium + large order: 20% discount
Final discount: 20%
When to Flatten Nested Conditions
Deeply nested conditions become hard to read quickly. When you find yourself nesting three or more levels deep, flattening with and is usually cleaner:
# Nested — harder to follow
if user_type == "premium":
if age >= 18:
if not is_banned:
print("Access granted")
# Flat — same logic, much easier to read
if user_type == "premium" and age >= 18 and not is_banned:
print("Access granted")
The flat version is preferred unless the inner decision needs its own else branch that is meaningfully different from the outer one.
Truthy and Falsy Values — Writing Cleaner Conditions
In Python, every value has an implicit boolean interpretation. You do not always need == True or == False — Python evaluates the value directly.
Falsy values — these evaluate to False in a condition:
False
None
0 # integer zero
0.0 # float zero
"" # empty string
[] # empty list
{} # empty dict
() # empty tuple
set() # empty set
Everything else is truthy — evaluates to True.
name = "Alice"
items = [1, 2, 3]
count = 0
message = ""
# Verbose — unnecessary
if name != "":
print("Name provided")
# Pythonic — uses truthy evaluation
if name:
print("Name provided")
# Check if a list has items
cart = ["laptop", "mouse"]
if cart:
print(f"Cart has {len(cart)} items")
else:
print("Cart is empty")
# Output: Cart has 2 items
# Check if a value exists
user_input = "Mumbai".strip()
if user_input:
city = user_input
else:
city = "Unknown"
The not shortcut for empty checks:
errors = []
if not errors:
print("No errors found") # runs because [] is falsy, not errors is True
This pattern appears constantly in real Python code. Learn to read it naturally.
Ternary Expressions — One-Line Conditionals
A ternary expression (also called a conditional expression) assigns one of two values based on a condition, all in a single line:
# Standard syntax
value_if_true if condition else value_if_false
age = 20
status = "adult" if age >= 18 else "minor"
print(status) # adult
score = 73
grade = "Pass" if score >= 60 else "Fail"
print(grade) # Pass
# Inside an f-string
is_enrolled = True
print(f"Status: {'Active' if is_enrolled else 'Inactive'}")
# Output: Status: Active
When to Use Ternary Expressions
Use them for simple, readable one-liners where both outcomes are clear. Avoid them when the condition or either value is complex — a regular if/else is always clearer when the logic needs to breathe:
# Good — simple and readable
label = "even" if number % 2 == 0 else "odd"
# Avoid — too complex for one line, use if/else instead
result = process_a(x) if x > 0 and y < 100 and not flag else process_b(x, y, z)
Chained Comparisons — A Python Exclusive
Python supports chaining comparison operators in a way most other languages do not. This checks whether a value falls within a range cleanly:
age = 25
# Other languages require this
if age >= 18 and age <= 65:
print("Working age")
# Python allows this — equivalent and more readable
if 18 <= age <= 65:
print("Working age")
score = 83
if 80 <= score < 90:
print("Grade B")
temperature = 22
if 15 < temperature < 30:
print("Comfortable temperature")
Chained comparisons read exactly like mathematical notation and are unambiguous. Use them whenever you are checking ranges.
The match Statement (Python 3.10+) — Clean Multi-Branch Logic
Python 3.10 introduced match — a structural pattern matching statement that handles multiple specific value checks more cleanly than long elif chains:
command = "quit"
match command:
case "start":
print("Starting the application")
case "stop":
print("Stopping the application")
case "quit":
print("Quitting and saving")
case "help":
print("Showing help menu")
case _:
print(f"Unknown command: {command}")
Output:
Quitting and saving
The case _: is the default — equivalent to else. It matches anything not caught by earlier cases.
# Match with multiple values per case
day = "Saturday"
match day:
case "Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday":
print("Weekday")
case "Saturday" | "Sunday":
print("Weekend")
case _:
print("Invalid day")
# Output: Weekend
match vs elif: use match when checking one variable against specific literal values — it is cleaner and more readable. Use if/elif when conditions involve ranges, comparisons, or multiple variables.
Real-World Conditional Patterns
These are the patterns that appear most frequently in actual Python programs.
Pattern 1: Input Validation
def validate_age(age_input):
if not isinstance(age_input, int):
return "Error: age must be an integer"
if age_input < 0:
return "Error: age cannot be negative"
if age_input > 150:
return "Error: age is unrealistically high"
return f"Valid age: {age_input}"
print(validate_age(25)) # Valid age: 25
print(validate_age(-5)) # Error: age cannot be negative
print(validate_age("old")) # Error: age must be an integer
Pattern 2: Early Return — The Guard Clause
Instead of nesting logic deeper and deeper, return early when a condition fails. This flattens the code significantly:
# Deeply nested — hard to follow
def process_order(user, cart, payment):
if user is not None:
if len(cart) > 0:
if payment["valid"]:
# actual processing logic buried 3 levels deep
return "Order processed"
else:
return "Invalid payment"
else:
return "Cart is empty"
else:
return "User not found"
# Guard clauses — same logic, much more readable
def process_order(user, cart, payment):
if user is None:
return "User not found"
if len(cart) == 0:
return "Cart is empty"
if not payment["valid"]:
return "Invalid payment"
# actual processing logic at the top level, unobstructed
return "Order processed"
Guard clauses are one of the most impactful readability improvements you can make to Python functions. You will see this pattern in every professional codebase.
Pattern 3: Membership Testing
VALID_CATEGORIES = {"electronics", "clothing", "food", "books", "sports"}
category = "electronics".strip().lower()
if category in VALID_CATEGORIES:
print(f"Valid category: {category}")
else:
print(f"Invalid category. Choose from: {', '.join(sorted(VALID_CATEGORIES))}")
Pattern 4: Status-Based Routing
def handle_response(status_code):
if 200 <= status_code < 300:
return "Success"
elif 300 <= status_code < 400:
return "Redirect"
elif 400 <= status_code < 500:
return "Client error"
elif 500 <= status_code < 600:
return "Server error"
else:
return "Unknown status"
print(handle_response(200)) # Success
print(handle_response(404)) # Client error
print(handle_response(500)) # Server error
A Complete Working Program
Here is a loan eligibility checker that uses every conditional concept from this chapter in a realistic scenario:
# Loan eligibility checker
def check_loan_eligibility(applicant):
name = applicant["name"]
age = applicant["age"]
income = applicant["monthly_income"]
credit_score = applicant["credit_score"]
existing_loans = applicant["existing_loans"]
employment = applicant["employment_type"]
# Guard clauses — reject immediately if hard disqualifiers
if age < 21 or age > 65:
return name, "Rejected", "Age must be between 21 and 65"
if employment == "unemployed":
return name, "Rejected", "Must be employed"
if credit_score < 600:
return name, "Rejected", f"Credit score {credit_score} below minimum 600"
# Determine loan tier
if credit_score >= 750 and income >= 80000 and existing_loans == 0:
tier = "Premium"
max_loan = income * 60
interest_rate = 7.5
elif credit_score >= 700 and income >= 50000 and existing_loans <= 1:
tier = "Standard"
max_loan = income * 40
interest_rate = 10.5
elif credit_score >= 650 and income >= 30000:
tier = "Basic"
max_loan = income * 20
interest_rate = 14.0
else:
return name, "Rejected", "Does not meet minimum combined criteria"
return name, "Approved", f"{tier} tier | Max loan: ₹{max_loan:,} | Rate: {interest_rate}%"
# Test applicants
applicants = [
{"name": "Priya Sharma", "age": 32, "monthly_income": 90000,
"credit_score": 780, "existing_loans": 0, "employment_type": "salaried"},
{"name": "Arjun Mehta", "age": 19, "monthly_income": 25000,
"credit_score": 680, "existing_loans": 0, "employment_type": "salaried"},
{"name": "Cleo Park", "age": 45, "monthly_income": 60000,
"credit_score": 720, "existing_loans": 1, "employment_type": "salaried"},
{"name": "Ravi Kumar", "age": 38, "monthly_income": 35000,
"credit_score": 590, "existing_loans": 2, "employment_type": "self-employed"},
{"name": "Maya Torres", "age": 28, "monthly_income": 45000,
"credit_score": 660, "existing_loans": 0, "employment_type": "unemployed"},
]
print(f"{'Name':<15} {'Decision':<10} {'Details'}")
print("-" * 70)
for applicant in applicants:
name, decision, details = check_loan_eligibility(applicant)
print(f"{name:<15} {decision:<10} {details}")
Output:
Name Decision Details
----------------------------------------------------------------------
Priya Sharma Approved Premium tier | Max loan: ₹5,400,000 | Rate: 7.5%
Arjun Mehta Rejected Age must be between 21 and 65
Cleo Park Approved Standard tier | Max loan: ₹2,400,000 | Rate: 10.5%
Ravi Kumar Rejected Credit score 590 below minimum 600
Maya Torres Rejected Must be employed
Every concept from this chapter appears here — guard clauses, elif chains, and conditions, range checks, and a clean top-to-bottom decision structure.
5 Conditional Mistakes Every Beginner Makes
Mistake 1: Using = instead of == in conditions
age = 18
# if age = 18: # SyntaxError in Python 3
# print("Adult")
if age == 18: # correct
print("Adult")
Mistake 2: Wrong elif order catches the wrong branch
score = 95
# Wrong — score 95 matches >= 60 first, gets grade D
if score >= 60:
grade = "D"
elif score >= 90:
grade = "A" # never reached for score 95
# Correct — most restrictive first
if score >= 90:
grade = "A"
elif score >= 60:
grade = "D"
Mistake 3: Comparing to True or False explicitly
is_active = True
if is_active == True: # works but verbose
print("Active")
if is_active: # Pythonic — same result
print("Active")
if not is_active: # cleaner than is_active == False
print("Inactive")
Mistake 4: Forgetting the colon
# if age >= 18 # SyntaxError: expected ':'
# print("Adult")
if age >= 18: # correct
print("Adult")
Mistake 5: Misunderstanding and vs or in exclusion logic
day = "Saturday"
# Wrong — this can never be True
# No single value can equal both "Saturday" AND "Sunday" simultaneously
if day == "Saturday" and day == "Sunday":
print("Weekend") # never prints
# Correct
if day == "Saturday" or day == "Sunday":
print("Weekend")
# Even cleaner
if day in ("Saturday", "Sunday"):
print("Weekend")
The and vs or confusion when checking one variable against multiple values is extremely common. When you want "matches any of these values", use in with a tuple or set — it is cleaner than multiple or conditions.
Practice: Conditional Statement Exercises
Exercise 1: Grade classifier
Write a function classify_grade(score) that returns "A" for 90+, "B" for 80-89, "C" for 70-79, "D" for 60-69, and "F" below 60. Test it with scores 95, 82, 71, 65, and 45.
Exercise 2: FizzBuzz
Write a program that checks a number and prints "FizzBuzz" if divisible by both 3 and 5, "Fizz" if divisible by 3 only, "Buzz" if divisible by 5 only, or the number itself otherwise. Test with 15, 9, 10, and 7.
Exercise 3: Login validator
Write a function that takes a username and password. Return "Access granted" only if username is not empty, password is at least 8 characters, and username is not in a banned list {"admin", "root", "test"}. Return a specific error message for each failure case.
Exercise 4: Shipping cost calculator
Write a function that calculates shipping cost based on weight and membership. Members pay half price. Weights up to 1kg cost ₹50, 1-5kg cost ₹120, 5-10kg cost ₹200, and above 10kg cost ₹350. Test with several combinations.
Exercise 5: Leap year checker
A year is a leap year if it is divisible by 4, except century years (divisible by 100) are not leap years unless also divisible by 400. Write a function is_leap_year(year) that returns True or False. Test with 2000, 1900, 2024, and 2023.
→ See all Python practice exercises with solutions
For all topics, see Python exercises.
What Comes Next — Day 9: Loops and Iteration
Conditionals let your program choose a path. Loops let your program repeat a path — processing every item in a list, running until a condition changes, iterating through a dictionary. With the data structures from Days 5-7 and the conditional logic from today, loops in Day 9 will let you build programs that handle real collections of data automatically.
Day 9 covers:
- for loops — iterating over sequences
- while loops — repeating until a condition is false
- range() — generating number sequences
- enumerate() — loops with index awareness
- break, continue, and else on loops
- Nested loops for 2D data
→ Continue to Day 9: Loops and Iteration
Chapter navigation
- Previous: Day 7: Dictionaries
- Next: Day 9: Loops and Iteration
Frequently asked questions: Conditional statements
What are conditional statements in Python?
Conditional statements are code structures that execute different blocks depending on whether a condition evaluates to True or False. Python uses if for the primary condition, elif for additional conditions, and else for the fallback when no condition matches. They are the fundamental mechanism for decision-making in any program.
What is the difference between if, elif, and else in Python?
if checks the first condition. elif checks additional conditions only if all previous conditions were False — you can have as many elif branches as needed. else runs when no if or elif condition matched. Exactly one branch runs per if/elif/else chain — never more than one, never zero if else is present.
Why does the order of elif conditions matter in Python?
Python evaluates conditions top to bottom and executes the first matching branch, skipping all the rest. If a broader condition appears before a more specific one, the specific case is never reached. For overlapping range checks, always put the most restrictive condition first.
What is a ternary expression in Python?
A ternary expression is a one-line conditional that assigns one of two values: value_if_true if condition else value_if_false. It is equivalent to a two-branch if/else but written in a single expression. Use it for simple, readable assignments — avoid it when the condition or either value is complex.
What are truthy and falsy values in Python?
Every Python value has an implicit boolean interpretation. Falsy values evaluate to False in conditions: False, None, 0, 0.0, "", [], {}, (), and set(). Everything else is truthy. This lets you write if name: instead of if name != "" and if cart: instead of if len(cart) > 0.
What is a guard clause in Python?
A guard clause is an early return or raise at the top of a function that handles error or edge cases immediately, before the main logic. Instead of nesting the happy path inside multiple if blocks, guard clauses reject invalid inputs at the top and leave the main logic flat and readable. This pattern is widely used in professional Python code.
What is the difference between and and or in Python conditions?
and requires every condition to be True — one False makes the whole expression False. or requires at least one condition to be True — only returns False when every condition is False. A common mistake is using and when checking one variable against multiple values: day == "Saturday" and day == "Sunday" can never be True. Use or or in for multiple value checks.
What is the match statement in Python?
match was introduced in Python 3.10 as a structural pattern matching statement. It checks one expression against multiple specific patterns — cleaner than a long elif chain when comparing a variable against literal values. The case _: at the end serves as the default fallback, equivalent to else.
Related Page
Day 7: Dictionaries
Learn about day 7: dictionaries
Learn MoreDay 9: Loops and Iteration
Continue with day 9: loops and iteration
Learn MorePython exercises hub
165+ programs with solutions
Learn MorePython quiz
Multiple-choice checks with explanations
Learn MoreConditional statement programs
if/elif/else and decision logic practice
Learn More