Dataslope logoDataslope

Control Flow

if, elif, else, the conditional expression, and structural pattern matching

Every decision in software is a conditional. From "should I cache this result?" to "is the user authorized?" to "which HTTP status code do I return?", control flow is the engine that routes execution through different paths. Python's control flow is straightforward: if, elif, else, and (since Python 3.10) a match statement for pattern matching.

Every snippet on this page runs in your browser — no setup required.

Real-world impact

Conditionals are not just syntax — they are the logical heart of every program. A web server routes requests with if method == "GET". A data pipeline filters invalid rows with if is_valid(row). A game checks if player.health <= 0. You write conditionals hundreds of times a day. Mastering them means writing clear, correct, maintainable logic.

Just if

The simplest form: execute a block only if a condition is true.

Code Block
Python 3.13.2
Code Block
Python 3.13.2

If the condition is false, the block is skipped entirely.

Code Block
Python 3.13.2

if + elif

When you have multiple mutually exclusive conditions, use elif (short for "else if").

Code Block
Python 3.13.2

Python evaluates the conditions in order and stops at the first true one.

Code Block
Python 3.13.2

Even though x > 5 is also true, only "a" prints because the first branch matches.

Full if / elif / else

Add an else block to catch all remaining cases.

Code Block
Python 3.13.2

There can be any number of elif branches; else is optional. Each branch needs its own indented body (no braces).

Code Block
Python 3.13.2

Truthiness in conditions

The if condition is evaluated for truthiness, not strict equality with True. See the Booleans page for the full rules. In short: 0, "", [], {}, None, and False are falsy; everything else is truthy.

Code Block
Python 3.13.2
Code Block
Python 3.13.2

Use if items: to check for non-empty sequences. Use if x is None: for explicit None checks. Use if x: for general "does this have a meaningful value?" checks. All three are idiomatic.

Conditional expression (ternary)

When you need a value, not a statement, use the inline form:

<value_if_true> if <condition> else <value_if_false>
Code Block
Python 3.13.2
Code Block
Python 3.13.2

This reads naturally: "pick X if condition, else pick Y." It combines nicely with f-strings and comprehensions.

The conditional expression requires both the if and else parts. You cannot write x if condition without an else. If you only need the if, write a full if statement instead.

Chained comparisons

Python lets you chain comparison operators, which usually reads more naturally than a > 0 and a < 10.

Code Block
Python 3.13.2
Code Block
Python 3.13.2

This is not syntactic sugar for separate comparisons; Python evaluates each term only once, which matters if the term has side effects.

Code Block
Python 3.13.2

match statement (Python 3.10+)

match is structural pattern matching, not just a switch. It matches the shape of data and can bind values from inside it.

Code Block
Python 3.13.2

Patterns can also match class instances, dict shapes, and sequences of varying lengths. See PEP 634 for the full reference.

Code Block
Python 3.13.2

Why no switch before 3.10?

Before Python 3.10, Python deliberately had no switch. The community preferred chained if/elif or, for value-to-value mappings, a dict lookup. The match statement was added not to replace those patterns, but to enable structural pattern matching — destructuring complex data shapes in one expression.

Dict-based dispatch (alternative to switch)

For simple value-to-value mappings, a dict is often clearer than if/elif or match.

Code Block
Python 3.13.2

This pattern is especially useful when the mapping is data-driven (e.g., loaded from a config file).

The walrus operator

Python 3.8 added the walrus operator :=, which assigns a value inside an expression. This is useful in conditionals:

if (n := len(items)) > 10:
    print(f"Too many items: {n}")

It saves a line by combining the assignment and the check. Use sparingly — only when it genuinely improves readability.

Challenges

Challenge
Python 3.13.2
FizzBuzz, the classic

Define a function fizzbuzz(n) that returns a list of length n where the i-th element (1-indexed) is:

  • "FizzBuzz" if i is divisible by both 3 and 5
  • "Fizz" if i is divisible by 3 only
  • "Buzz" if i is divisible by 5 only
  • The string form of i otherwise
Challenge
Python 3.13.2
Leap year

A year is a leap year if it is divisible by 4, except century years (divisible by 100), which must also be divisible by 400. Define is_leap(year) returning True or False.

Challenge
Python 3.13.2
Grade calculator

Define a function letter_grade(score) that returns the letter grade for a numeric score:

  • "A" for 90-100
  • "B" for 80-89
  • "C" for 70-79
  • "D" for 60-69
  • "F" for below 60

Assume score is an integer between 0 and 100.

QuestionSelect one

What does this print?

x = 7
if x > 0:
  print("a")
elif x > 5:
  print("b")
else:
  print("c")

a

b

a then b

c

QuestionSelect one

Which match case matches a 2-tuple only when its two elements are equal (e.g. (4, 4))?

Hint: a guard is an if condition written after the pattern.

case (x, y):

case (x, y) if x == y:

case x and y:

case (x, x):

QuestionSelect one

What is the value of result after this code?

x = 5
result = "big" if x > 10 else "small"

"big"

"small"

None

A SyntaxError

QuestionSelect one

Which expression is equivalent to 0 < x < 10?

(0 < x) < 10

0 < x and x < 10

0 < (x < 10)

x in range(1, 10)

Next: looping.

On this page