Python online course

Nested if Statements in Python

Learn how nested if, if-else, and if-elif-else statements work in Python, including indentation, execution flow, input validation, and logical alternatives.

A nested if statement is an if-based conditional located inside another conditional block. Nesting lets a program make a second decision only after a related first decision has been made.

For example, a program can first check whether a user is logged in and then, only for logged-in users, check whether the user has administrator permissions.

A conditional statement chooses which code to run based on whether a condition evaluates to the Boolean value True or False. An if statement runs its block when its condition is true; an else statement provides a fallback when the associated condition is false.

What Makes an If Statement Nested?

Nesting means placing one conditional statement inside the body of another conditional branch. The inner condition is relevant only after Python enters the outer branch that contains it.

is_logged_in = True
is_admin = False

if is_logged_in:
    if is_admin:
        print("Show administrator tools")

Python evaluates is_logged_in first. Only when that condition is true does Python evaluate is_admin.

This differs from two independent, sequential if statements:

if is_logged_in:
    print("Show the account")

if is_admin:
    print("Show administrator tools")

With independent statements, Python evaluates both conditions separately. With nesting, the inner check depends on reaching the outer block.

Basic Nested If Syntax

The general pattern has an outer if followed by an inner if that is indented one additional level.

if outer_condition:
    if inner_condition:
        action_when_both_are_true

Indentation defines Python's blocks. A block is a group of statements controlled by a header such as if, elif, or else. Use four spaces for each indentation level.

An inner else can be added inside the outer branch:

if outer_condition:
    if inner_condition:
        print("Both conditions are true")
    else:
        print("The outer condition is true, but the inner condition is false")

The inner conditional is skipped if outer_condition is false, because execution never enters its containing block.

Nested If-Else Syntax and Branch Association

A nested structure can have both an inner else and an outer else:

if outer_condition:
    if inner_condition:
        print("Outer true and inner true")
    else:
        print("Outer true and inner false")
else:
    print("Outer false")

Each else belongs to the if at the same indentation level. The first else is indented to the same level as if inner_condition, so it belongs to the inner if. The second else aligns with if outer_condition, so it belongs to the outer if.

Outer conditionInner conditionCode path selectedExample classification
FalseNot evaluatedOuter elseNot eligible
TrueTrueInner ifEligible and approved
TrueFalseInner elseEligible but not approved

Indentation and Python Block Structure

Python uses leading whitespace to determine block membership instead of curly braces. Every statement controlled by a conditional header must be indented.

if account_exists:                 # level 0
    if password_is_correct:        # level 1
        print("Signed in")         # level 2
    else:                           # level 1
        print("Incorrect password")
else:                               # level 0
    print("Account not found")

The inner if is one additional indentation level beneath the outer branch. Incorrect indentation can change which branch an else belongs to, change program behavior, or raise an IndentationError. Do not mix tabs and spaces; conventionally use four spaces per level.

Execution Flow in a Nested Decision

  1. Python evaluates the outer condition.
  2. If the outer condition is false, Python skips every statement in that outer if block and runs the outer else, if present.
  3. If the outer condition is true, Python enters the block and evaluates the inner condition.
  4. Python runs either the inner if block or the inner else block.
  5. After the selected block finishes, execution continues after the complete nested structure.

For the pattern above, there are three practical routes: outer false; outer true and inner true; or outer true and inner false. There is no inner result on the first route because the inner condition was never evaluated.

Example: Minimum and Maximum Age Check

Suppose an age must be at least 18 and no greater than 65. The outer condition checks the minimum. Only qualifying ages receive the upper-bound check.

MINIMUM_AGE = 18
MAXIMUM_AGE = 65

try:
    age = int(input("Enter your age: "))

    if age < MINIMUM_AGE:
        print("Below the minimum age")
    else:
        if age > MAXIMUM_AGE:
            print("Above the maximum age")
        else:
            print("Age is in the accepted range")
except ValueError:
    print("Please enter a whole number")

input() returns text, so int() converts valid numeric text to an integer before comparisons are performed. Text that is not a valid integer, such as "eighteen" or an empty string, causes int() to raise ValueError. The try-except block handles that invalid input.

Representative inputOuter testInner testOutput category
15FalseSkippedBelow minimum
30TrueFalseAccepted range
70TrueTrueAbove maximum

This is a dependent check: the upper-bound test matters only after the minimum-age test succeeds.

Nested If Statements with Elif

elif means “else if.” It is an additional branch tested after a preceding if or elif condition is false. Use elif for mutually exclusive conditions at the same logical level.

An inner conditional can contain an if-elif-else chain:

has_ticket = True
seat_class = "business"

if has_ticket:
    if seat_class == "first":
        print("First-class seat")
    elif seat_class == "business":
        print("Business-class seat")
    else:
        print("Standard seat")
else:
    print("Ticket required")

The outer conditional can also have elif branches:

status = "paused"

if status == "active":
    print("Running")
elif status == "paused":
    if has_ticket:
        print("Paused with access")
    else:
        print("Paused without access")
elif status == "closed":
    print("Closed")
else:
    print("Unknown status")

More Than Two Levels of Nesting

An if can be placed inside another nested branch, creating three or more levels of control flow.

value = "42"

if value:
    if value.isnumeric():
        number = int(value)
        if 1 <= number <= 100:
            print("Valid value")
        else:
            print("Number is outside the allowed range")
    else:
        print("Value is not numeric")
else:
    print("A value is required")

Each deeper condition adds another indentation level. This example validates presence, then numeric form, then range. Deeper nesting can express dependent validation, but excessive nesting makes control flow harder to read. Consider elif, logical operators, helper functions, or early returns when they make the intent clearer.

Logical Operators as an Alternative

A logical operator combines or reverses Boolean conditions. and requires both conditions to be true, or requires at least one to be true, and not inverts a Boolean result.

The accepted-age test can be flattened into a single inclusive range check:

age = int(input("Enter your age: "))

if 18 <= age <= 65:
    print("Age is in the accepted range")
else:
    print("Age is outside the accepted range")

The same logic can be written with and:

if age >= 18 and age <= 65:
    print("Age is in the accepted range")

Nesting is useful when the second test genuinely depends on the first or when each stage needs a different response. A compound condition is often clearer when several related tests simply determine one result.

StructureBest use caseExample patternReadability note
ifRun code for one conditionif ready:Simple single decision
if-elseChoose between two outcomesif valid: ... else: ...Exactly one branch runs
if-elif-elseChoose among mutually exclusive same-level casesif x == 1: ... elif x == 2: ... else: ...Usually clearer than many separate if statements
Nested ifPerform a dependent second checkif signed_in: if is_admin:Shows staged decisions, but adds indentation
Compound conditionCombine related Boolean testsif minimum <= value <= maximum:Compact when the logic remains easy to understand

Practical Dependent-Check Examples

Account Permissions

if is_logged_in:
    if is_admin:
        print("Administrator access granted")
    else:
        print("Signed in, but administrator access is not available")
else:
    print("Please sign in first")

The authorization check occurs only after authentication succeeds.

Weather Activity

if is_raining:
    if has_umbrella:
        print("You can go outside with your umbrella")
    else:
        print("Choose an indoor activity")
else:
    print("Choose an outdoor activity")

The umbrella check is relevant only when it is raining. When it is not raining, the outer else is selected and the inner check is skipped.

Common Mistakes

  • Misaligned else: An else belongs to the if at the same indentation level. Align it with the intended conditional.
  • Incorrect indentation: Indent each block consistently by four spaces. Missing indentation or mixed tabs and spaces can raise IndentationError.
  • Expecting the inner test to run after an outer false result: Nested code runs only after execution enters its enclosing block.
  • Using separate if statements for exclusive results: Separate statements can print multiple messages. Use an if-elif-else chain or an appropriate nested structure when exactly one result should be selected.
  • Comparing input text with an integer: input() returns a string. Convert numeric text with int() before numeric comparisons.
  • Ignoring invalid input: int(input(...)) can raise ValueError. Validate the input or handle the exception with try and except.
  • Over-nesting: Many indentation levels can hide the main logic. Refactor with elif, and/or, helper functions, or early returns where appropriate.

Troubleshooting Nested Conditionals

ProblemLikely causeResolution
The else branch runs unexpectedlyIt is aligned with a different if than intendedInspect indentation and align else with its associated if
IndentationErrorA block body is not indented, or tabs and spaces are mixedUse consistent four-space indentation
The inner condition does not runThe outer condition evaluated to FalseTest the outer condition with an input that enters its block
TypeError during numeric comparisonThe value from input() is still a stringConvert valid numeric text with int()
ValueError after calling int()The input was not numericValidate the text or catch ValueError
Several classification messages printIndependent if statements were usedUse mutually exclusive if-elif-else branches

Summary

  • A nested if places one conditional inside another conditional block.
  • Python evaluates the outer condition first and evaluates the inner condition only when its containing branch is reached.
  • Indentation determines block membership and which else belongs to which if.
  • Use nesting for dependent, staged decisions such as authentication followed by authorization.
  • Use elif for mutually exclusive conditions at the same logical level.
  • Use and, or, and not when a compound Boolean condition is clearer.
  • Convert numeric input with int() and handle possible ValueError exceptions.
  • Refactor deeply nested code when a flatter structure improves readability.

For related syntax, review the Python if statement, if-else statements, if-elif statements, and logical operators. For input conversion, see getting user input and numeric variables.