Python Nested if Statements
Nested if Statements
A nested if statement is an if statement placed inside another if (or elif / else) block. It lets a program make decisions in layers: the inner condition is evaluated only if the outer condition is true.
Nested conditions are useful when one decision depends on the result of another. For example, an ATM first checks whether your card is valid, and only then checks whether your PIN is correct, and only then checks whether you have enough balance.
Syntax
if outer_condition:
# runs when outer_condition is True
if inner_condition:
# runs when BOTH conditions are True
else:
# runs when outer is True but inner is False
else:
# runs when outer_condition is False
Each level of nesting is indented by another 4 spaces. Indentation tells Python which else belongs to which if.
Basic Nested if Example
Example: Checking Number Ranges
number = 28
if number > 15:
print("Number is greater than 15")
if number > 25:
print("Number is also greater than 25")
else:
print("But it is not greater than 25")
Expected output:
Number is greater than 15
Number is also greater than 25
Step by step:
- The outer condition
28 > 15isTrue, so Python enters the outer block and prints the first message. - Inside, Python evaluates the inner condition
28 > 25, which is alsoTrue. - The inner
ifblock runs. The innerelseis skipped.
Try number = 20: the outer block runs, but the inner condition is False, so the output is "Number is greater than 15" followed by "But it is not greater than 25". With number = 10, nothing is printed, because the outer condition fails and the inner check never happens.
How Nested if Statements Work
Python evaluates nested conditions from the outside in. If the outer condition fails, the entire inner block — including any nested conditions — is skipped.
Example: Voting Eligibility Check
age = 22
citizen = True
if age >= 18:
if citizen:
print("Eligible to vote")
else:
print("Citizenship required")
else:
print("Not old enough to vote")
Expected output:
Eligible to vote
age | citizen | Output |
|---|---|---|
| 22 | True | Eligible to vote |
| 22 | False | Citizenship required |
| 16 | True or False | Not old enough to vote |
A key advantage of nesting is visible here: each failure gets its own specific message. The user learns exactly why they are not eligible.
Matching else Blocks Correctly
The position of an else — its indentation — decides which if it belongs to. In the example above:
- The inner
else(indented 4 spaces) pairs withif citizen:. - The outer
else(not indented) pairs withif age >= 18:.
Misaligning an else changes the program's logic, so pay close attention to indentation in nested code.
Multiple Levels of Nesting
You can nest if statements several levels deep, but each level makes the code harder to follow. Aim for clarity.
Example: Academic Evaluation
marks = 78
attendance_rate = 85
project_submitted = False
if marks >= 50:
if attendance_rate >= 75:
if project_submitted:
print("Course completed successfully")
else:
print("Project submission pending")
else:
print("Insufficient attendance")
else:
print("Failed due to low marks")
Expected output:
Project submission pending
How Python reaches this result:
marks >= 50→78 >= 50isTrue. Enter level 1.attendance_rate >= 75→85 >= 75isTrue. Enter level 2.project_submittedisFalse, so the level-3elseruns.
Each requirement is checked only after the previous one passes, and each failure produces a specific message.
Nested if vs Logical Operators
Some nested conditions can be simplified with the logical operator and. Both approaches are valid; choose the one that is clearer for the situation.
Nested if Version
speed = 70
seatbelt_on = True
if speed <= 80:
if seatbelt_on:
print("Safe to continue driving")
Using the and Operator
speed = 70
seatbelt_on = True
if speed <= 80 and seatbelt_on:
print("Safe to continue driving")
Expected output (both versions):
Safe to continue driving
Both produce the same result. The and version is flatter and easier to read.
Which Should You Choose?
- Use nested
ifwhen conditions are dependent — when the inner check only makes sense after the outer one passes — or when each failure needs a different response. - Use logical operators when the conditions are simple, equally important, and lead to a single outcome.
Practical Examples
Example 1: User Authentication Flow
email_entered = "user@example.com"
password_entered = "secure@123"
account_verified = False
if email_entered:
if password_entered:
if account_verified:
print("Access granted")
else:
print("Please verify your account")
else:
print("Password is missing")
else:
print("Email is required")
Expected output:
Please verify your account
email_enteredis a non-empty string, so it is truthy.password_enteredis also non-empty and truthy.account_verifiedisFalse, so the innermostelseruns.
Each step of the login flow has its own message, which helps the user understand what to fix.
Example 2: Performance Rating System
Nested statements can also appear inside elif and else branches, or an if–elif–else chain can contain a nested if:
performance_score = 88
bonus_awarded = True
if performance_score >= 85:
if bonus_awarded:
print("Excellent performance with bonus")
else:
print("Excellent performance")
elif performance_score >= 70:
print("Good performance")
else:
print("Needs improvement")
Expected output:
Excellent performance with bonus
The bonus check only matters for top performers, so it is nested inside the first branch.
Reducing Deep Nesting
Deeply nested code (three or more levels) is often called "arrow code" because of its shape. One common way to flatten it, especially inside functions, is to handle failure cases first and exit early:
def check_login(email, password, verified):
if not email:
return "Email is required"
if not password:
return "Password is missing"
if not verified:
return "Please verify your account"
return "Access granted"
print(check_login("user@example.com", "secure@123", False))
Expected output:
Please verify your account
This version has the same logic as the nested authentication example, but every condition sits at the same indentation level. Each return ends the function immediately, so later checks run only when earlier ones pass. (You will learn about functions and return in the Python Functions lesson.)
Common Mistakes
| Mistake | Problem |
|---|---|
Misaligned else | The else attaches to the wrong if, changing the logic |
| Nesting too deeply | Code becomes hard to read and maintain |
Nesting when and is enough | Adds unnecessary indentation |
Using and when each failure needs a different message | Loses the ability to explain which condition failed |
| Mixing tabs and spaces in nested blocks | TabError or IndentationError |
Related Concepts
- Python if Statement — single conditions
- Python elif and else Statements — multi-way decisions
- Python Operators —
and,or, andnot - Python Functions — using early
returnto flatten nested logic