if / elif / else

The Course
•
January 6, 2026
•
6 min read

An if statement runs a block of code only when a condition is true.

Your first branch Python
age = int(input("Age: "))

if age >= 18:
    print("You may enter.")
    print("Enjoy the show.")

print("Goodbye")

Three details matter here:

  1. The condition ends with a colon.
  2. The lines that belong to the if are indented — four spaces, by convention.
  3. print("Goodbye") is not indented, so it runs either way.

Indentation is how Python marks a block. Other languages use braces; Python uses the layout you would have used anyway.

else and elif

else catches everything the if did not. elif (“else if”) adds another question, and you can chain as many as you like.

Grading Python
score = int(input("Score out of 100: "))

if score >= 90:
    grade = "A"
elif score >= 80:
    grade = "B"
elif score >= 70:
    grade = "C"
elif score >= 60:
    grade = "D"
else:
    grade = "F"

print(f"Score {score} earns a {grade}")

Order matters enormously. Python checks the branches top to bottom and stops at the first true one — so a score of 95 never reaches the >= 80 test. Write the chain the wrong way round (>= 60 first) and every passing score becomes a D.

elif is not the same as a second if

A chain of elifs picks exactly one branch. A run of separate ifs tests every condition independently, and several can fire. Both are useful — but they mean different things.

One branch, or many Python
n = 15

print("With elif:")
if n % 3 == 0:
    print("  divisible by 3")
elif n % 5 == 0:
    print("  divisible by 5")

print("With separate ifs:")
if n % 3 == 0:
    print("  divisible by 3")
if n % 5 == 0:
    print("  divisible by 5")

Nesting, and how to avoid it

An if can contain another if. It can, but deeply nested conditions get hard to follow fast.

Nested versus flat Python
username = input("Username: ")
password = input("Password: ")

# Nested: the happy path is buried at the deepest indent.
if username:
    if password:
        if len(password) >= 6:
            print("Welcome back")
        else:
            print("Password too short")
    else:
        print("Password required")
else:
    print("Username required")

The same logic reads far better as a series of early exits, each handling one problem and getting out of the way:

Guard clauses Python
username = input("Username: ")
password = input("Password: ")

if not username:
    print("Username required")
elif not password:
    print("Password required")
elif len(password) < 6:
    print("Password too short")
else:
    print("Welcome back")

Same behaviour, one level of indentation, and every rule sits on its own line.

The conditional expression

When a whole if/else exists only to choose between two values, Python has a one-line form:

A value, chosen inline Python
count = 1

label = "item" if count == 1 else "items"
print(f"{count} {label}")

temperature = 31
print("hot" if temperature > 30 else "not hot")

Use it for short, obvious choices. If you find yourself nesting one inside another, go back to a normal if.

Before you write your own

Predict. How many lines does this print, and which ones?

What will this print? Python
spent = 75

if spent > 100:
    print("over budget")
elif spent > 50:
    print("getting close")
elif spent > 20:
    print("fine")
else:
    print("barely started")

if spent > 70:
    print("check your receipts")
Check your prediction
getting close
check your receipts

75 is also greater than 20, but the elif chain stops at its first true branch, so fine never prints. The last if is a separate statement — not part of the chain — so it’s tested on its own.

Fix. Orders of 50 or more ship free, 20 or more get reduced shipping, and anything smaller pays the standard rate. An order of 65 should print free. It doesn’t.

Shipping bands Python
order = 65

if order >= 20:
    band = "reduced"
elif order >= 50:
    band = "free"
else:
    band = "standard"

print(band)
Check your fix
order = 65

if order >= 50:
    band = "free"
elif order >= 20:
    band = "reduced"
else:
    band = "standard"

print(band)
free

With >= 20 first, every order of 20 or more stops there — the >= 50 branch can never run. Put the narrowest condition first.

Exercise

Fizz, Buzz, or the number

Print Fizz if the number divides by 3, Buzz if it divides by 5, FizzBuzz if it divides by both, and otherwise the number itself. Try it with 9, 10, 15 and 7, which should print Fizz, Buzz, FizzBuzz and 7.

n = int(input("Number: "))

# Your code here
Hint 1: the idea

There are four outcomes, and one of them — FizzBuzz — is true exactly when Fizz and Buzz both are. After the fix above, you know what that means for the order of your branches. n % 3 == 0 asks “does n divide by 3?”.

Hint 2: a first step

Start with the most specific case: if n % 3 == 0 and n % 5 == 0:. The other three follow as an elif chain, ending in an else that prints n itself.

Show one solution
n = int(input("Number: "))

if n % 3 == 0 and n % 5 == 0:
    print("FizzBuzz")
elif n % 3 == 0:
    print("Fizz")
elif n % 5 == 0:
    print("Buzz")
else:
    print(n)

The combined case has to come first. Test it against 15 and you will see why — put it last and 15 prints Fizz, because that branch matched before the FizzBuzz test was ever reached.

What you learned

  • if condition: runs an indented block when the condition is true.
  • elif adds alternatives; else catches the rest; exactly one branch runs.
  • Order your conditions from most specific to least.
  • Guard clauses beat deep nesting.
  • a if condition else b chooses between two values inline.
Last updated on January 6, 2026

Was this article helpful?

Your response is saved on this device.