if, elif & else
Conditional statements let a program make decisions. Python's if runs a block only when a condition is true, elif ("else if") checks further conditions in turn, and else catches everything left over.
if
balance = 120 price = 80 if balance >= price: print("Purchase approved") balance -= price print("Balance:", balance)
Purchase approved Balance: 40
The condition is followed by a colon, and the block is indented. When the condition is false, the indented block is skipped.
else
hour = 20 if hour < 18: print("Good afternoon") else: print("Good evening")
Good evening
elif
Conditions are checked from top to bottom, and only the first true branch runs:
def grade(score): if score >= 90: return "A" elif score >= 80: return "B" elif score >= 70: return "C" elif score >= 60: return "D" else: return "F" for s in [95, 83, 71, 64, 30]: print(s, grade(s))
95 A 83 B 71 C 64 D 30 F
Because the checks happen in order, the second condition doesn't need to say score < 90 — that's already guaranteed if we got that far.
Combining conditions
age = 25 has_ticket = True is_vip = False if age >= 18 and has_ticket: print("Welcome in") if is_vip or age >= 65: print("Free drink") else: print("Drinks are $5") if not is_vip: print("Join our VIP club!") temperature = 22 if 18 <= temperature <= 25: print("Perfect weather")
Welcome in Drinks are $5 Join our VIP club! Perfect weather
Chained comparisons like 18 <= temperature <= 25 are a Python nicety that reads just like maths.
Checking membership
command = "quit" if command in ("exit", "quit", "q"): print("Goodbye!") allowed = {"admin", "editor"} role = "viewer" if role not in allowed: print(f"{role!r} cannot edit")
Goodbye! 'viewer' cannot edit
Testing against a tuple or set with in is cleaner than chaining command == "exit" or command == "quit" or ….
Truthiness in conditions
items = [] name = "Ana" if items: print(f"{len(items)} items") else: print("No items") if name: print(f"Hello, {name}")
No items Hello, Ana
Nested ifs vs guard clauses
Deeply nested conditions are hard to read. Inside functions, returning early for the special cases keeps the main path flat:
def checkout(user, cart): if user is None: return "Please log in" if not cart: return "Your cart is empty" if not user.get("verified"): return "Please verify your email" return f"Charging {user['name']} for {len(cart)} items" print(checkout(None, ["book"])) print(checkout({"name": "Ana", "verified": True}, ["book", "pen"]))
Please log in Charging Ana for 2 items
Conditional expressions
For choosing between two values, the one-line conditional expression is often clearer:
stock = 3 label = "in stock" if stock > 0 else "sold out" print(label) count = 1 print(f"{count} {'item' if count == 1 else 'items'}")
in stock 1 item
pass: an empty block
A block can't be empty in Python. Use pass as a placeholder while you're still writing code:
debug = False if debug: pass # TODO: add logging else: print("running normally")
running normally