Python Nested If
Beginner Control Flow

Python Nested If

1Python Nested If: overview

A nested if is an if statement placed inside another if (or else) block, so a second question is only asked after the first one has been answered.

GoalBy the end you can write nested if statements with correct indentation, decide when nesting is the natural choice, put an elif ladder inside an if, and flatten deep nesting with and or by checking the problems first.

Before this lesson: Python if, elif and else, Python Logical Conditions

2Python Nested If: diagram

Python Nested Ifage = 20, has_ticket = Trueif age >= 18:first question; False: "Adults only"Trueif has_ticket:second question, asked only after a True aboveTrueprint("Welcome in")both answers were yes
The inner if sits one level deeper and is only reached when the outer condition is True. If the age check fails, Python skips the whole inner block without ever asking about the ticket.

3Python Nested If: explained step by step

Some questions only make sense after an earlier one has been answered. You don't ask a passenger which seat they would like until you know they have a ticket. In code that means placing one if inside another: a nested if. The inner question is asked only when the outer condition is True.

An if inside an if

Python
age = 20
has_ticket = True

if age >= 18:
    print("Age check passed")
    if has_ticket:
        print("Welcome in")
    else:
        print("Please buy a ticket first")
else:
    print("Adults only")

Every if / else pair is its own decision. The inner if sits one level deeper (four more spaces), and the inner else lines up with the inner if, so it belongs to it. The outer else, back at the left edge, belongs to the outer if. Try has_ticket = False, then age = 15, and watch which message appears.

Indentation is the structure

Python has no braces. The left edge of each line tells you which block it belongs to. To read nested code, find an else and look straight up for the if with exactly the same indentation: that is its partner.

if outer_question:
    if inner_question:
        ...      # outer True, inner True
    else:
        ...      # outer True, inner False
else:
    ...          # outer False: the inner question was never asked
print("done")    # back at the left edge: always runs

When nesting is the natural choice

Nest when the second question depends on the first, or when each answer to the first question leads to different follow-up questions. An elif ladder fits inside an if just as it does anywhere else. Here only members get a tiered discount, so non-members never even reach the ladder:

Python
is_member = True
total = 85

if is_member:
    if total >= 100:
        discount = 20
    elif total >= 50:
        discount = 10
    else:
        discount = 5
else:
    discount = 0
print(f"Discount: {discount}%")

Flattening with and

When an outer if contains nothing but one inner if, and neither has an else, you can merge the two tests with and. These two blocks do exactly the same thing:

Python
age = 20
has_ticket = True

if age >= 18:
    if has_ticket:
        print("Nested: welcome in")

if age >= 18 and has_ticket:
    print("Flat: welcome in")

The flat version is shorter. Keep the nesting when you want to say which test failed: "Adults only" and "Please buy a ticket first" are different messages, and a single and can't tell them apart.

Check the problems first

Deeply nested code drifts further and further to the right, which makes it hard to follow. A calmer layout deals with the unhappy cases first, one per line, and leaves the normal case for the end. With elif it looks like this:

Python
age = 20
has_ticket = False
is_banned = False

if is_banned:
    print("Entry refused")
elif age < 18:
    print("Adults only")
elif not has_ticket:
    print("Please buy a ticket first")
else:
    print("Welcome in")

Inside a function there is an even neater version. Each check ends with return, which hands back an answer and leaves the function immediately, so the code never gets deeper than one level. This is called a guard clause:

def entry_message(age, has_ticket):
    if age < 18:
        return "Adults only"
    if not has_ticket:
        return "Please buy a ticket first"
    return "Welcome in"

How deep is too deep?

Two levels are normal. At three, look for a simpler shape. Beyond that, flatten with and, check the problems first, or move the inner part into its own function. And if the outer question has many possible answers instead of yes/no, a match statement may express it better.

Quick reference: Python Nested If

4Python Nested If: syntax

if outer_condition:
    # runs when outer_condition is True
    if inner_condition:
        ...        # outer True and inner True
    else:
        ...        # outer True, inner False
else:
    ...            # outer False (the inner if was never checked)

# flattened, when there is no else and one action:
if outer_condition and inner_condition:
    ...

5Python Nested If: run the example

Press Run (or Ctrl + Enter). The output (step 6) appears directly below the code. Change anything and run it again.

Interactive example
balance = 250
card_inserted = True
pin_correct = True
amount = 300

if card_inserted:
    if pin_correct:
        if amount <= balance:
            print("Dispensing", amount)
        else:
            shortfall = amount - balance
            print("Insufficient funds, you are short by", shortfall)
    else:
        print("Wrong PIN")
else:
    print("Please insert your card")
print("Thank you for banking with us")
Expected outputInsufficient funds, you are short by 50
Thank you for banking with us

7Python Nested If: how the example works

Hover or tap a step to highlight its lines in the example above.

  1. Line 1-4The situation at the cash machine: a balance, two True/False flags and the amount requested.
  2. Line 6First question: is there a card? card_inserted is True, so Python enters the block at indentation level 1.
  3. Line 7Second question, asked only because there is a card. pin_correct is True, so Python goes one level deeper.
  4. Line 8Third question: 300 <= 250 is False, so the block on line 9 is skipped.
  5. Line 10-12This else lines up with if amount <= balance, so it is the partner of that test. It works out the shortfall (300 - 250 = 50) and reports it.
  6. Line 13-16The else on line 13 belongs to if pin_correct and the one on line 15 belongs to if card_inserted. Neither branch runs, because their conditions were True.
  7. Line 17Back at the left edge, outside every if, so this line runs no matter which branch was taken.

8Python Nested If: common mistakes

Attaching the else to the wrong if

✗ Wrong

age = 20
has_ticket = False

if age >= 18:
    if has_ticket:
        print("Welcome in")
else:
    print("Please buy a ticket first")
No error, but this adult without a ticket sees no message at all (and a child would be told to buy a ticket)

✓ Right

age = 20
has_ticket = False

if age >= 18:
    if has_ticket:
        print("Welcome in")
    else:
        print("Please buy a ticket first")
else:
    print("Adults only")

An else belongs to the if with the same indentation. Here it lines up with the outer if, so it only runs when the age check fails. Indent it to match the inner if, and give the outer else its own message.

Forgetting to indent the inner block

✗ Wrong

age = 20
has_ticket = True
if age >= 18:
    if has_ticket:
    print("Welcome in")
IndentationError: expected an indented block after 'if' statement on line 4

✓ Right

age = 20
has_ticket = True
if age >= 18:
    if has_ticket:
        print("Welcome in")

Every if needs a block that is indented deeper than the if itself. The print must be indented one more level than if has_ticket:.

Leaving the dependent line outside the if

✗ Wrong

items = []
if len(items) > 0:
    print("Items found")
print("First item:", items[0])
IndexError: list index out of range

✓ Right

items = []
if len(items) > 0:
    print("Items found")
    print("First item:", items[0])
else:
    print("The list is empty")

The last line needs a non-empty list, so it belongs inside the if that checks for one. At the left edge it runs no matter what the check said.

Flattening away a useful message

✗ Wrong

age = 15
has_ticket = True
if age >= 18 and has_ticket:
    print("Welcome in")
else:
    print("Not allowed")
No error, but the visitor is never told whether the age or the ticket was the problem

✓ Right

age = 15
has_ticket = True
if age < 18:
    print("Adults only")
elif not has_ticket:
    print("Please buy a ticket first")
else:
    print("Welcome in")

A single and can only say that something failed, not what. When each failure needs its own message, keep the questions separate with nested ifs or an elif ladder.

9Python Nested If: exercises

Write your answer, then press Check. The checks run in your browser.

1. Ticket first, then seat

Write code Easy

A cinema only asks about the seat once the customer has a ticket. Write a nested if that sets message:

  • no ticket (has_ticket is False): "Buy a ticket first"
  • ticket but seat is an empty string "": "Choose a seat"
  • ticket and a seat: "Enjoy the film"

Then print message. Try other values to see each message, then set them back to has_ticket = True and seat = "" before pressing Check.

Your code
has_ticket = True
seat = ""

# nested if: first check has_ticket, then check seat inside it

2. Follow the nested flow

Predict the output Medium

Read the code and type exactly what it prints. Pay attention to indentation: which else belongs to which if, and which lines are in the same block.

Read this code
score = 72
attended = False

if score >= 50:
    if attended:
        print("Pass")
    else:
        print("Pass, but attendance missing")
    if score >= 90:
        print("Distinction")
    elif score >= 70:
        print("Merit")
else:
    print("Fail")
print("Result recorded")

2 more exercises → 5 more examples

Finished this lesson?
Progress is saved in this browser — create a free account to keep it across devices.

Questions learners ask

How many levels of nested if can Python handle?

Python's parser allows about 100 levels of indentation, so the language itself is not the limit. Readability is: two levels are comfortable, three are a warning sign, and beyond that you should flatten with and, check the problems first, or move the inner part into a function.

Should I use a nested if or the and operator?

If there is no else branch and the inner if leads to a single action, and is simpler. If each failing question needs its own response, or the inner questions differ between branches, keep the nesting (or use an elif ladder) so the logic stays visible.

What is the difference between a nested if and elif?

elif belongs to the same chain as the if above it and is only checked when every earlier condition was False, so at most one branch of the chain runs. A nested if lives inside a branch, so it is only reached when the outer condition was True, and it can contain its own full if / elif / else.

Further reading

10Next lesson

Up nextPython Shorthand If (Ternary)Shorthand if gives you two compact forms: a one-line if statement for a single action, and the conditional expression `…

Related:
Python Logical ConditionsPython match StatementPython Functions

← Python Logical Conditions · All Control Flow lessons · Practise in the IDE