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.
Before this lesson: Python if, elif and else, Python Logical Conditions
2Python Nested If: diagram
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
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:
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:
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:
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
- Python Program to Check Leap Year — A year is a leap year if it is divisible by 4, except century years, which must also be divisible by 400; in …
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.
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.
- Line 1-4The situation at the cash machine: a balance, two True/False flags and the amount requested.
- Line 6First question: is there a card?
card_insertedis True, so Python enters the block at indentation level 1. - Line 7Second question, asked only because there is a card.
pin_correctis True, so Python goes one level deeper. - Line 8Third question:
300 <= 250is False, so the block on line 9 is skipped. - Line 10-12This
elselines up withif amount <= balance, so it is the partner of that test. It works out the shortfall (300 - 250 = 50) and reports it. - Line 13-16The
elseon line 13 belongs toif pin_correctand the one on line 15 belongs toif card_inserted. Neither branch runs, because their conditions were True. - 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")✓ 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")✓ 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])✓ 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")✓ 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 ✓ CompletedA cinema only asks about the seat once the customer has a ticket. Write a nested if that sets message:
- no ticket (
has_ticketisFalse):"Buy a ticket first" - ticket but
seatis 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.
has_ticket = True
seat = ""
# nested if: first check has_ticket, then check seat inside it
has_ticket = True
seat = ""
if has_ticket:
if seat == "":
message = "Choose a seat"
else:
message = "Enjoy the film"
else:
message = "Buy a ticket first"
print(message)
2. Follow the nested flow
Predict the output Medium ✓ CompletedRead 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.
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")Pass, but attendance missing
Merit
Result recorded
2 more exercises → 5 more examples
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