Ad – 728Γ—90
πŸ”€ Control Flow

Python If Statements – The Complete Guide

Programs that can only execute code in a straight line from top to bottom are severely limited. If statements give your program the ability to make decisions β€” to execute one block of code when a condition is true and a different block when it isn't. This lesson covers the complete if/elif/else syntax, writing effective boolean expressions, the concise ternary operator, nested conditionals, and real-world patterns used by professional Python developers every day.

⏱️ 25 min read 🎯 Beginner πŸ“… Updated 2026

What Is an If Statement?

An if statement is a conditional control structure that tests whether an expression is true and, if so, executes a block of code. If the condition is false, that block is skipped.

Think of it like a fork in the road: your program evaluates a condition and takes the left road (if true) or the right road (if false). Without if statements, every program would always take the same road, regardless of its data.

The basic structure:

Python
if condition:
    # code runs when condition is True
    statement_1
    statement_2
    # ... more statements

# code here always runs (outside the if block)
πŸ’‘
Python Uses Indentation, Not Braces

In Python, code blocks are defined by indentation (4 spaces or 1 tab β€” be consistent). There are no curly braces {} like in C, Java, or JavaScript. This forces readable code but means indentation errors cause real bugs.

Python
# A simple if statement
temperature = 35

if temperature > 30:
    print("It's hot outside!")
    print("Stay hydrated.")

print("Have a nice day.")  # Always runs
β–Ά Output
It's hot outside! Stay hydrated. Have a nice day.
Python
# When condition is False, the block is skipped
temperature = 20

if temperature > 30:
    print("It's hot outside!")   # skipped
    print("Stay hydrated.")       # skipped

print("Have a nice day.")        # runs
β–Ά Output
Have a nice day.

if…else: Two-Way Branching

An else clause provides an alternative block of code to execute when the condition is False. Exactly one of the two branches always runs.

Python
age = 17

if age >= 18:
    print("Welcome! You may enter.")
    print("Please show your ticket.")
else:
    print("Sorry, you must be 18 or older.")
    print("Come back soon!")

print("--- End of check ---")
β–Ά Output
Sorry, you must be 18 or older. Come back soon! --- End of check ---
Python
# Practical: even or odd
number = 42

if number % 2 == 0:
    print(f"{number} is even")
else:
    print(f"{number} is odd")
β–Ά Output
42 is even

if…elif…else: Multi-Way Branching

When you have more than two possible outcomes, use elif (short for "else if") to chain conditions. Python checks each condition in order and executes the block of the first one that is True. The else at the end is a catch-all that runs only if none of the previous conditions matched.

Python
score = 78

if score >= 90:
    grade = "A"
    message = "Excellent!"
elif score >= 80:
    grade = "B"
    message = "Good job!"
elif score >= 70:
    grade = "C"
    message = "Satisfactory."
elif score >= 60:
    grade = "D"
    message = "Needs improvement."
else:
    grade = "F"
    message = "Please see your instructor."

print(f"Score: {score}")
print(f"Grade: {grade}")
print(f"Feedback: {message}")
β–Ά Output
Score: 78 Grade: C Feedback: Satisfactory.
⚠️
Order Matters with elif

Python stops at the first matching condition. If you put a less-specific condition before a more-specific one, the more-specific one will never run. Always put more specific conditions first. For example, put score >= 90 before score >= 80, not after.

Python
# Real-world: shipping cost calculator
def get_shipping_cost(weight_kg):
    """Return shipping cost based on package weight."""
    if weight_kg <= 0:
        return "Error: weight must be positive"
    elif weight_kg <= 0.5:
        return 3.99
    elif weight_kg <= 2.0:
        return 6.49
    elif weight_kg <= 5.0:
        return 9.99
    elif weight_kg <= 20.0:
        return 15.99
    else:
        return 29.99  # heavy freight

print(get_shipping_cost(0.3))   # 3.99
print(get_shipping_cost(1.5))   # 6.49
print(get_shipping_cost(10))    # 15.99
print(get_shipping_cost(50))    # 29.99
β–Ά Output
3.99 6.49 15.99 29.99
Ad – 336Γ—280

Boolean Expressions in Conditions

The condition in an if statement can be any expression that Python can evaluate as truthy or falsy. This gives you enormous flexibility.

Python
# Comparing values
x = 10
if x == 10:
    print("x is exactly 10")

# Combining conditions with and, or, not
age = 22
has_ticket = True
is_vip = False

if age >= 18 and has_ticket:
    print("You may enter the concert")

if is_vip or age > 60:
    print("Enjoy priority seating")

if not is_vip:
    print("Join the regular queue")

# Truthy/falsy β€” no explicit comparison needed
username = "alice"
if username:               # True because non-empty string
    print(f"Hello, {username}!")

empty_name = ""
if not empty_name:         # True because empty string is falsy
    print("Please enter your name")

# None check
result = None
if result is None:
    print("No result computed yet")

# List / collection emptiness
items = [1, 2, 3]
if items:
    print(f"Cart has {len(items)} items")

empty_cart = []
if not empty_cart:
    print("Your cart is empty")
β–Ά Output
x is exactly 10 You may enter the concert Join the regular queue Hello, alice! Please enter your name No result computed yet Cart has 3 items Your cart is empty
πŸ’‘
Pythonic Truthiness Checks

Instead of if len(my_list) > 0:, write if my_list:. Instead of if name != "":, write if name:. Instead of if value != None:, write if value is not None:. These Pythonic forms are more concise and idiomatic.

The Ternary Operator (Conditional Expression)

Python's ternary operator compresses a simple if/else into a single line. The syntax is:

value_if_true if condition else value_if_false

Python
# Standard if/else
age = 20
if age >= 18:
    status = "adult"
else:
    status = "minor"
print(status)  # adult

# Equivalent ternary operator β€” one line!
status = "adult" if age >= 18 else "minor"
print(status)  # adult

# More examples
score = 85
label = "Pass" if score >= 60 else "Fail"
print(label)  # Pass

x = 7
print("even" if x % 2 == 0 else "odd")  # odd

# In f-strings
name = "Alice"
greeting = f"Hello, {name.title()}!" if name else "Hello, Guest!"
print(greeting)  # Hello, Alice!

# Nested ternary β€” use sparingly, can hurt readability
score = 75
grade = "A" if score >= 90 else ("B" if score >= 80 else ("C" if score >= 70 else "F"))
print(grade)  # C

# Assigning the larger of two values
a, b = 15, 22
maximum = a if a > b else b
print(maximum)  # 22
# Note: Python also has: max(a, b) for this specific case
β–Ά Output
adult adult Pass odd Hello, Alice! C 22
⚠️
Don't Overuse Ternary Operators

Ternary operators are great for simple, readable expressions. Avoid chaining multiple ternary operators together β€” it quickly becomes unreadable. If the condition and both outcomes don't all fit comfortably on one line, use a regular if/else block instead.

Nested If Statements

You can place if statements inside other if statements. This is called nesting. Use it when a second condition only makes sense to check after the first one passes.

Python
# Nested if: ATM withdrawal logic
balance = 500
withdrawal_amount = 200
pin_correct = True

if pin_correct:
    print("PIN accepted.")
    if withdrawal_amount <= balance:
        balance -= withdrawal_amount
        print(f"Dispensing ${withdrawal_amount}.")
        print(f"Remaining balance: ${balance}")
    else:
        print(f"Insufficient funds. Balance: ${balance}")
else:
    print("Incorrect PIN. Access denied.")

print("Transaction complete.")
β–Ά Output
PIN accepted. Dispensing $200. Remaining balance: $300 Transaction complete.
Python
# Nested if: classifying a number
def classify_number(n):
    if n == 0:
        return "zero"
    else:
        if n > 0:
            if n < 10:
                return "small positive"
            elif n < 100:
                return "medium positive"
            else:
                return "large positive"
        else:  # n < 0
            if n > -10:
                return "small negative"
            else:
                return "large negative"

print(classify_number(0))     # zero
print(classify_number(5))     # small positive
print(classify_number(75))    # medium positive
print(classify_number(1000))  # large positive
print(classify_number(-3))    # small negative
print(classify_number(-500))  # large negative
β–Ά Output
zero small positive medium positive large positive small negative large negative
πŸ’‘
Avoid Deep Nesting: Use Early Returns

Deeply nested if statements (more than 2–3 levels) become hard to read. A common technique is the "guard clause" or "early return" pattern: check for invalid conditions first and return early, keeping the main logic at the top level.

Guard Clauses and Early Returns

A guard clause is an if statement at the start of a function that handles edge cases and returns early, avoiding deep nesting. This is a widely-used professional pattern.

Python
# ❌ Deeply nested approach
def process_order_bad(user, items, payment):
    if user is not None:
        if items:
            if payment:
                if payment > 0:
                    # actual logic buried 4 levels deep!
                    total = sum(items)
                    return f"Order placed! Total: ${total}"
                else:
                    return "Invalid payment amount"
            else:
                return "No payment provided"
        else:
            return "Cart is empty"
    else:
        return "User not logged in"

# βœ… Guard clause approach β€” much cleaner
def process_order(user, items, payment):
    if user is None:
        return "User not logged in"
    if not items:
        return "Cart is empty"
    if not payment:
        return "No payment provided"
    if payment <= 0:
        return "Invalid payment amount"

    # Main logic at the top level β€” easy to read!
    total = sum(items)
    return f"Order placed! Total: ${total}"

# Test both functions
print(process_order(None, [10, 20], 30))      # User not logged in
print(process_order("alice", [], 30))          # Cart is empty
print(process_order("alice", [10, 20], 30))   # Order placed! Total: $30
β–Ά Output
User not logged in Cart is empty Order placed! Total: $30

Common If Statement Patterns

Pattern 1: Input Validation

Python
def get_discount(age, is_member):
    """Calculate discount percentage based on age and membership."""
    if age < 0 or age > 120:
        raise ValueError(f"Invalid age: {age}")

    if age < 5:
        return 100  # free for toddlers
    elif age < 12:
        return 50   # half price for children
    elif age >= 65:
        return 30   # senior discount
    elif is_member:
        return 15   # member discount
    else:
        return 0    # full price

print(get_discount(3, False))    # 100
print(get_discount(8, False))    # 50
print(get_discount(70, False))   # 30
print(get_discount(30, True))    # 15
print(get_discount(30, False))   # 0

Pattern 2: State Machine

Python
def get_traffic_action(signal_color):
    """Determine driving action based on traffic light color."""
    if signal_color == "green":
        return "Go"
    elif signal_color == "yellow":
        return "Prepare to stop"
    elif signal_color == "red":
        return "Stop"
    else:
        return f"Unknown signal: {signal_color}"

for color in ["green", "yellow", "red", "blue"]:
    action = get_traffic_action(color)
    print(f"{color.upper()}: {action}")
β–Ά Output
GREEN: Go YELLOW: Prepare to stop RED: Stop BLUE: Unknown signal: blue

Pattern 3: Range Checking

Python
def categorize_bmi(bmi):
    """Categorize Body Mass Index."""
    if bmi < 18.5:
        return "Underweight"
    elif 18.5 <= bmi < 25:
        return "Normal weight"
    elif 25 <= bmi < 30:
        return "Overweight"
    else:
        return "Obese"

# Test with several BMI values
test_values = [16.0, 22.5, 27.3, 35.1]
for bmi in test_values:
    print(f"BMI {bmi}: {categorize_bmi(bmi)}")
β–Ά Output
BMI 16.0: Underweight BMI 22.5: Normal weight BMI 27.3: Overweight BMI 35.1: Obese

match…case (Python 3.10+)

Python 3.10 introduced the match statement (structural pattern matching) as an alternative to long chains of elif. It's similar to switch in other languages but much more powerful.

Python
def describe_command(command):
    match command:
        case "quit" | "exit" | "q":
            return "Exiting the program"
        case "help" | "h" | "?":
            return "Showing help menu"
        case "save":
            return "Saving your work"
        case "load":
            return "Loading saved state"
        case _:           # default case (like else)
            return f"Unknown command: '{command}'"

print(describe_command("quit"))    # Exiting the program
print(describe_command("help"))    # Showing help menu
print(describe_command("save"))    # Saving your work
print(describe_command("foo"))     # Unknown command: 'foo'
β–Ά Output
Exiting the program Showing help menu Saving your work Unknown command: 'foo'
πŸ’‘
match vs if/elif

Use match when comparing a single variable against a set of specific literal values β€” it's cleaner than a long elif chain. Use if/elif for range checks, complex boolean conditions, or when you need to support Python versions below 3.10.

πŸ‹οΈ Practical Exercise

Write a Python function calculate_tax(income) that computes income tax using these brackets:

  • $0 – $10,000: 0% tax
  • $10,001 – $40,000: 10% tax on the amount over $10,000
  • $40,001 – $85,000: $3,000 + 22% on the amount over $40,000
  • Over $85,000: $12,900 + 32% on the amount over $85,000

The function should raise a ValueError if income is negative. Print a formatted tax statement for incomes of $5,000, $25,000, $60,000, and $120,000.

πŸ”₯ Challenge Exercise

Build a text-based "Magic 8-Ball" program. The user enters a yes/no question. Use a random number (0–7 from random.randint) to select one of 8 responses. Group the responses with if/elif/else into three categories: positive (responses 0–2), neutral (3–4), and negative (5–7). For the positive and negative categories, use nested if/elif to select the specific message within each group. Print the question, the numeric response index, the category, and the specific response. Use the ternary operator somewhere to format the output.

Interview Questions on If Statements

  • What is the difference between if/elif/else and multiple separate if statements?
  • What is a "truthy" value in Python? Give 5 examples of falsy values.
  • What is the ternary (conditional) operator in Python? Write an example.
  • What is a guard clause and why is it preferred over deeply nested if statements?
  • Why does the order of elif conditions matter? Give an example of a bug caused by wrong order.
  • What is the match statement introduced in Python 3.10?
  • How does Python's and short-circuit evaluation interact with if statements?
  • What is the "Pythonic" way to check if a list is empty before processing it?

πŸ“‹ Summary

  • The if statement executes a block only when its condition is True; indentation defines the block.
  • else provides a fallback block when the if condition is False.
  • elif allows multiple conditions to be tested in sequence; Python stops at the first match.
  • The order of elif conditions matters β€” more specific conditions should come first.
  • The ternary operator x if condition else y compresses simple if/else into one line.
  • Nested if statements work but should be limited to 2–3 levels; use guard clauses (early returns) to avoid deep nesting.
  • Any truthy/falsy value can be used as a condition β€” you don't always need explicit comparisons.
  • Python 3.10+ offers the match statement for clean pattern-matching against literal values.

Frequently Asked Questions

What is the difference between "if a:" and "if a is not None:"? +

if a: checks if a is truthy β€” it returns False for None, 0, "", [], and other falsy values. if a is not None: only checks that a is not None β€” it would pass for 0, "", and []. Use is not None when you specifically want to allow the values 0, False, or empty collections as valid, non-None values.

Can I have an if statement without an else? +

Yes, absolutely. An else clause is optional. If you only want code to run when a condition is true and nothing special should happen otherwise, just use a plain if without else. For example: if debug_mode: print("Debug info") β€” when debug_mode is False, nothing happens and execution continues normally.

Can I have elif without else? +

Yes. else is always optional. An if/elif without else means that if none of the conditions match, no branch runs and the program continues after the entire if/elif chain. This is perfectly valid and common when the "no match" case means "do nothing."

Is there a switch or case statement in Python? +

Python 3.10 introduced the match statement, which provides pattern matching similar to switch/case in other languages. For Python versions before 3.10, the common alternatives are: a chain of if/elif/else statements, or a dictionary mapping values to results/functions. The dictionary approach is especially clean: result = actions.get(key, default_action)().

When should I use a ternary operator vs a regular if/else? +

Use the ternary operator when: (1) the entire expression fits on one short, readable line, (2) you are assigning a single value based on a simple condition, and (3) both the true and false results are simple values (not complex expressions). Use a regular if/else when the condition is complex, when the blocks contain multiple statements, or when readability would suffer from a one-liner.