Skip to content
Laviyx Learn

Try

Python course menu

Python Nested if Statements (and How to Flatten Them)

Learn nested conditions in Python: if statements inside other ifs, when nesting is useful, how to flatten deep nesting with and, elif, and early returns (guard clauses), with a leap year example.

Beginner7 min readUpdated
On this page

A nested condition is an if statement inside another if (or else). It lets you make a second decision only after a first one has been made. Nesting is useful, but deep nesting quickly becomes hard to read, so this lesson also shows how to flatten it.

Example: entry to a show#

Python
age = 25
has_ticket = True

if age >= 18:
    if has_ticket:
        print("Enjoy the show")
    else:
        print("Please buy a ticket")
else:
    print("Adults only")
Output
Enjoy the show

The inner if/else is only reached when age >= 18. Each level of nesting adds another 4 spaces of indentation.

Flattening with elif#

The same logic can often be written without nesting by checking the "failure" cases first:

Python
age = 25
has_ticket = False

if age < 18:
    print("Adults only")
elif not has_ticket:
    print("Please buy a ticket")
else:
    print("Enjoy the show")
Output
Please buy a ticket

Every outcome is now at the same level, and the conditions read like a checklist.

Flattening with and#

When the inner if has no else, combine the conditions:

Python
# Nested
if age >= 18:
    if has_ticket:
        print("Enjoy the show")

# Flat: same behaviour
if age >= 18 and has_ticket:
    print("Enjoy the show")

A classic: leap years#

A year is a leap year if it is divisible by 4, except years divisible by 100, unless they are also divisible by 400. Nested, it looks like this:

Python
year = 2024

if year % 4 == 0:
    if year % 100 == 0:
        if year % 400 == 0:
            leap = True
        else:
            leap = False
    else:
        leap = True
else:
    leap = False

print(year, leap)
Output
2024 True

It works, but three levels of nesting are hard to follow. The same rule as one boolean expression:

Python
for year in [2024, 1900, 2000, 2026]:
    leap = year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
    print(year, leap)
Output
2024 True
1900 False
2000 True
2026 False

Guard clauses inside functions#

Inside a function, the cleanest way to avoid nesting is to return early when something is wrong. These early checks are called guard clauses:

Python
def can_withdraw(balance, amount, card_blocked):
    if card_blocked:
        return "Card blocked"
    if amount <= 0:
        return "Invalid amount"
    if amount > balance:
        return "Insufficient funds"
    return "Approved"

print(can_withdraw(1000, 300, False))
print(can_withdraw(1000, 3000, False))
print(can_withdraw(1000, 300, True))
Output
Approved
Insufficient funds
Card blocked

Each problem is handled and dismissed at the top, and the "happy path" sits at the end, unindented.

When nesting is fine#

Nesting is natural when the inner decision only makes sense after the outer one, and both branches of the outer decision have their own sub-decisions. One level of nesting is perfectly normal.

Common mistakes#

Practice#

Practice exercise

Write code that finds the largest of three numbers a, b and c using nested if statements (without max()), and test it on (3, 9, 5), (7, 2, 7) and (1, 1, 1). Compare with max(a, b, c).

Show hint

First compare a with b. Inside each branch, compare the winner with c.

Show solution
Python
for a, b, c in [(3, 9, 5), (7, 2, 7), (1, 1, 1)]:
    if a >= b:
        if a >= c:
            largest = a
        else:
            largest = c
    else:
        if b >= c:
            largest = b
        else:
            largest = c
    print(largest, max(a, b, c))
Output
9 9
7 7
1 1

In real code you would simply use max(a, b, c), but this exercise shows how nested decisions narrow down the answer.

Key takeaway#

Finished this lesson?