if, elif and else — Conditional Statements in Python

Conditional statements let your program make decisions — executing different code depending on whether a condition is true or false. Python’s conditional syntax is cleaner than most languages: no parentheses required around the condition, no curly braces, and a colon at the end of each clause. The if, elif, and else keywords are Python’s only conditional statement — there is no switch or case statement in Python (though match was added in Python 3.10 as a structural pattern matching tool). You will use conditionals constantly in FastAPI: checking authentication status, validating request data, and deciding which database query to run.

Basic if / elif / else

# Syntax: condition followed by colon, body is indented
age = 25

if age >= 18:
    print("Adult")

# if / else
if age >= 18:
    print("Adult")
else:
    print("Minor")

# if / elif / else — multiple conditions checked in order
score = 75

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"Grade: {grade}")   # Grade: C

# Only the FIRST matching branch runs — the rest are skipped
# Once a condition is True, Python does not check further elif/else
Note: Python uses a colon at the end of every if, elif, and else line, and the body must be indented by exactly 4 spaces (or a consistent number of spaces/tabs — but 4 spaces is the PEP 8 standard). Forgetting the colon is the single most common syntax error for new Python developers. Your code editor should highlight this immediately, but it is worth memorising: every control flow header line ends with a colon.
Tip: Python evaluates conditions using truthiness — you do not need to explicitly compare to True or False. Instead of if is_active == True:, write if is_active:. Instead of if name != "":, write if name: (truthy if non-empty). This is idiomatic Python and what you will see in FastAPI and SQLAlchemy source code. However, always use is None and is not None when checking for None — never rely on truthiness for None checks.
Warning: Python does not have a switch statement — use if/elif/else chains instead. If you have many branches based on a single value, consider a dictionary dispatch pattern (covered in Chapter 5) which is more Pythonic and faster for large numbers of cases. Python 3.10 introduced the match statement for structural pattern matching, but if/elif/else remains the standard for simple value comparisons.

Conditions and Truthiness

# Truthy values — evaluate to True in a boolean context
if 42:          print("non-zero int is truthy")
if 3.14:        print("non-zero float is truthy")
if "hello":     print("non-empty string is truthy")
if [1, 2, 3]:   print("non-empty list is truthy")
if {"a": 1}:    print("non-empty dict is truthy")

# Falsy values — evaluate to False
if not 0:       print("0 is falsy")
if not 0.0:     print("0.0 is falsy")
if not "":      print("empty string is falsy")
if not []:      print("empty list is falsy")
if not {}:      print("empty dict is falsy")
if not None:    print("None is falsy")
if not False:   print("False is falsy")

# Practical FastAPI examples
def get_post(post_id: int):
    post = db.get_post(post_id)   # returns None if not found
    if post is None:              # explicit None check — always use 'is'
        raise HTTPException(404)
    if not post.published:        # truthy check — published is bool
        raise HTTPException(403)
    return post

def search_posts(query: str):
    if not query:                 # checks for empty string or None
        return []                 # no query — return empty list
    return db.search(query)

The Ternary Expression

# Python ternary: VALUE_IF_TRUE if CONDITION else VALUE_IF_FALSE
# Note the order is different from JavaScript: condition ? true : false

age = 20
status = "adult" if age >= 18 else "minor"
print(status)   # "adult"

# JavaScript equivalent: age >= 18 ? "adult" : "minor"

# Practical uses
user_name = user.name if user else "Guest"
page_size  = limit if limit <= 100 else 100
label      = f"{count} item" if count == 1 else f"{count} items"

# Avoid nesting ternaries — hard to read
# Bad:
result = "a" if x > 0 else "b" if x < 0 else "c"  # confusing

# Better: use if/elif/else for three or more branches

Nested Conditions and Combining

# Nested conditions — indent each level
role = "admin"
is_active = True

if role == "admin":
    if is_active:
        print("Active admin — full access")
    else:
        print("Inactive admin — no access")
else:
    print("Regular user")

# Equivalent using 'and' — often cleaner
if role == "admin" and is_active:
    print("Active admin — full access")

# Checking membership
ALLOWED_ROLES = {"user", "editor", "admin"}   # set — O(1) lookup
if role in ALLOWED_ROLES:
    print(f"Role '{role}' is valid")

# FastAPI guard clause pattern — return early on failure
def update_post(post_id: int, user_id: int):
    post = db.get(post_id)
    if post is None:
        raise HTTPException(404, "Post not found")
    if post.author_id != user_id:
        raise HTTPException(403, "Not authorised")
    # Only reach here if post exists and user is the owner
    return db.update(post_id)

Common Mistakes

Mistake 1 — Missing the colon

❌ Wrong — colon missing after condition:

if age >= 18
    print("Adult")   # SyntaxError: expected ':'

✅ Correct — colon is required on every header line:

if age >= 18:
    print("Adult")   # ✓

Mistake 2 — Wrong indentation level

❌ Wrong — body not indented or inconsistently indented:

if age >= 18:
print("Adult")       # IndentationError — body must be indented

if age >= 18:
    print("Check 1")
  print("Check 2")   # IndentationError — inconsistent indent

✅ Correct — consistent 4-space indent for the body:

if age >= 18:
    print("Check 1")   # ✓ 4 spaces
    print("Check 2")   # ✓ same level

Mistake 3 — Using == True instead of truthiness

❌ Wrong — verbose comparison to True:

if is_active == True:   # works but un-Pythonic
    ...

✅ Correct — use truthiness directly:

if is_active:           # ✓ idiomatic Python
    ...

Quick Reference

Pattern Code
Simple if if condition:
if/else if condition: ... else: ...
if/elif/else if c1: ... elif c2: ... else: ...
Ternary value_a if condition else value_b
Membership check if item in collection:
None check if value is None:
Truthiness check if value: (non-empty, non-zero, not None)
Negative truthiness if not value:

🧠 Test Yourself

What does the following Python code print?
x = 0
print("yes" if x else "no")