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:
if condition:
# code runs when condition is True
statement_1
statement_2
# ... more statements
# code here always runs (outside the if block)
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.
# A simple if statement
temperature = 35
if temperature > 30:
print("It's hot outside!")
print("Stay hydrated.")
print("Have a nice day.") # Always runs
# 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
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.
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 ---")
# Practical: even or odd
number = 42
if number % 2 == 0:
print(f"{number} is even")
else:
print(f"{number} is odd")
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.
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}")
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.
# 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
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.
# 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")
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
# 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
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.
# 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.")
# 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
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.
# β 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
Common If Statement Patterns
Pattern 1: Input Validation
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
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}")
Pattern 3: Range Checking
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)}")
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.
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'
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/elseand multiple separateifstatements? - 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
elifconditions matter? Give an example of a bug caused by wrong order. - What is the
matchstatement introduced in Python 3.10? - How does Python's
andshort-circuit evaluation interact with if statements? - What is the "Pythonic" way to check if a list is empty before processing it?
π Summary
- The
ifstatement executes a block only when its condition isTrue; indentation defines the block. elseprovides a fallback block when theifcondition isFalse.elifallows multiple conditions to be tested in sequence; Python stops at the first match.- The order of
elifconditions matters β more specific conditions should come first. - The ternary operator
x if condition else ycompresses 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
matchstatement for clean pattern-matching against literal values.
Related Topics
Frequently Asked Questions
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.
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.
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."
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)().
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.