---
title: The match-case Statement in Python (Python's Switch)
source: https://app.sythra.ai/learn/python/match-case-python
topic: Python
updated: 2026-08-12
publisher: Sythra (https://app.sythra.ai)
---

# The match-case Statement in Python (Python's Switch)

Python 3.10 introduced match/case as a cleaner alternative to long if/elif chains for checking one value against many possibilities, with case _: as the required default case for anything unmatched.

_Source: [https://app.sythra.ai/learn/python/match-case-python](https://app.sythra.ai/learn/python/match-case-python) — free to read on Sythra._

## Key points

- Python has no traditional switch statement — use if/elif/else or match/case instead
- match/case was added in Python 3.10
- case _: is the wildcard default case and must always come last
- Combine values in one case with the | (or) symbol: case 1 | 2 | 3:
- Always include a default case — skipping it causes a silent failure on unmatched input
- Dictionary dispatch (dict.get(key, default_function)) is a popular alternative pattern

Many programming languages have something called a **switch statement** — a tool for checking one value against a whole list of possible cases and running different code depending on which one matches. For a very long time, **Python did not have this at all**; programmers just used [if/elif/else](/learn/python/conditionals-in-python) chains. Starting in Python 3.10, Python added its own version: **match/case**.

This page covers both approaches, and — most importantly — how to handle the situation where none of your cases match.

## What you will learn

- How to simulate a switch statement with `if`/`elif`/`else`
- The modern `match`/`case` syntax (Python 3.10+)
- Matching multiple values in one `case` with `|`
- Why a **default case** is not optional in practice
- Connecting cases to functions, including dictionary dispatch

## The old-school way: simulating "switch" with if/elif/else

Before `match`/`case` existed, here's how every Python programmer handled a "check one value against several options" situation:

```python
day = 4

if day == 1:
    print("Monday")
elif day == 2:
    print("Tuesday")
elif day == 3:
    print("Wednesday")
elif day == 5:
    print("Friday")
else:
    print("Unknown day")
```

Notice there's no `elif day == 4:` here, on purpose. So what happens when `day` is `4`? Python checks each condition top to bottom, finds none of them match, and falls all the way through to the final `else:` block. That `else` is your **default case** — the safety net that catches anything you didn't specifically plan for.

> **The single most important idea here:** 

## The modern way: match and case

Python 3.10 introduced a cleaner, more readable tool for exactly this situation: the `match` statement, paired with one or more `case` blocks.

```python
day = 4

match day:
    case 1:
        print("Monday")
    case 2:
        print("Tuesday")
    case 3:
        print("Wednesday")
    case 5:
        print("Friday")
    case _:
        print("Unknown day")
```

- `match day:` — "take the value stored in `day`, and compare it against each case below, top to bottom"
- `case 1:` — "if `day` equals 1, run this block", and so on for each case
- `case _:` — the special **default case**. The underscore `_` is a wildcard matching anything not already caught by an earlier case; it must always go **last**

Run this with `day = 4` and you'll get `Unknown day` printed, because there's no `case 4:` anywhere above it, so Python falls through to the wildcard `case _:` at the bottom — the exact same idea as the `else` block above.

> **Important rule:** 

## Matching multiple values in one case

Sometimes you want several different values to all trigger the same response. Group them together in a single `case` using the `|` symbol (meaning "or" in this context):

```python
day = 6

match day:
    case 1 | 2 | 3 | 4 | 5:
        print("Weekday")
    case 6 | 7:
        print("Weekend")
    case _:
        print("Not a valid day")
```

Here, `case 6 | 7:` means "if day is 6, OR if day is 7, run this block" — saving you from writing five nearly-identical `case` lines to print the same message five times.

## The default case is not optional in practice

Technically, Python will let you write a `match` statement, or an `if`/`elif` chain, with no default case at all:

```python
match day:
    case 1:
        print("Monday")
    case 2:
        print("Tuesday")
```

This runs perfectly fine — right up until someone passes in a value you didn't plan for, like `day = 4`. When that happens, nothing matches, nothing prints, and nothing crashes either. The program just quietly does nothing and moves on. This is called a **silent failure**, and it's one of the sneakiest kinds of bugs, because there's no error message to tell you something went wrong.

This is exactly why the golden habit of this page is: **every switch-style decision should end with a default case** — whether that's `else:` in an `if` chain, or `case _:` in a `match` statement. Think of it as a permanent safety net underneath your decision-making code.

## Connecting cases to functions

So far, each case has just printed a short message. In real programs, you usually want each case to do something more substantial — the cleanest way is to write a **separate function for each case**, and have your `match` simply decide _which function to call_.

```python
def handle_monday():
    print("Starting the work week — let's go!")

def handle_tuesday():
    print("Tuesday grind.")

def handle_friday():
    print("Almost the weekend!")

def handle_unknown_day():
    print("That's not a day I recognize.")


day = 4

match day:
    case 1:
        handle_monday()
    case 2:
        handle_tuesday()
    case 5:
        handle_friday()
    case _:
        handle_unknown_day()
```

Instead of cramming all the logic for "Monday" directly inside `case 1:`, we wrote a dedicated function `handle_monday()`, and the `case` block's only job is to call it. Since `day = 4` matches nothing above it, Python falls through to `case _:`, which calls `handle_unknown_day()`. This keeps each piece of logic small, named, and easy to find later.

## An even cleaner trick: dictionary dispatch

There's a popular pattern in Python for exactly this "pick a function based on a value" situation, which doesn't even need `match` or `if`/`elif` at all — it uses a **dictionary** to directly map each case to its matching function:

```python
def handle_monday():
    print("Starting the work week — let's go!")

def handle_tuesday():
    print("Tuesday grind.")

def handle_friday():
    print("Almost the weekend!")

def handle_unknown_day():
    print("That's not a day I recognize.")


day_functions = {
    1: handle_monday,
    2: handle_tuesday,
    5: handle_friday,
}

day = 4

# .get() looks up day_functions[4], finds nothing, and uses
# handle_unknown_day as the fallback default instead of crashing
chosen_function = day_functions.get(day, handle_unknown_day)
chosen_function()
```

Notice we wrote `handle_monday`, not `handle_monday()` — **no parentheses**. Without parentheses, we're referring to the function itself, like a tool sitting in a toolbox; with parentheses, we'd be calling it immediately. The dictionary stores the _tools themselves_, and we only "use" one once we've decided exactly which one we need.

The real magic is in `.get(day, handle_unknown_day)`. This dictionary method tries to look up `day` (which is `4`) inside `day_functions`; since there's no key `4`, instead of raising an error, `.get()` quietly returns the **second argument** — our default function `handle_unknown_day` — exactly like `case _:` or `else:` did earlier, just written in a completely different style. This pattern is extremely popular in real, professional Python code, especially with many possible cases, because it avoids a long wall of `case` or `elif` lines.

## Common mistakes

- Forgetting the default case (`else:` or `case _:`) and getting a silent failure on unexpected input
- Putting `case _:` anywhere except last — Python checks cases in order and stops at the first match
- Writing `handle_monday()` with parentheses inside a dictionary meant to store the function itself
- Assuming `match`/`case` is available in Python versions before 3.10

> **Practice with Sythra:**  [Practice with AI tutor](https://app.sythra.ai/pricing)

## FAQ

### Does Python have a switch statement?

Python does not have a traditional switch statement like C or Java. For most of Python's history, developers used if/elif/else chains instead. Python 3.10 introduced match/case, which serves a similar purpose.

### What Python version added match-case?

The match statement (structural pattern matching) was introduced in Python 3.10. It is not available in earlier Python versions.

### What does case _: mean in Python?

case _: is the wildcard default case in a match statement. The underscore matches anything not already caught by an earlier case, and must always be placed last since Python checks cases in order.

### How do you match multiple values in one case?

Use the | (or) symbol inside a single case, like case 1 | 2 | 3:, which runs that block if the matched value is 1, 2, or 3.

### What happens if no case matches and there's no default case?

If no case matches and there's no case _: default, the match statement does nothing at all — no error, no output. This silent failure can hide bugs, so a default case is considered essential in practice.

### What is dictionary dispatch in Python?

Dictionary dispatch maps values to functions in a dictionary, then uses dict.get(key, default_function) to look up and call the matching function, falling back to a default if the key isn't found — an alternative to a long match or if/elif chain.

## Related

- [Conditionals in Python (if, elif, else)](https://app.sythra.ai/learn/python/conditionals-in-python) — The classic way to simulate a switch statement.
- [Comparison Operators in Python](https://app.sythra.ai/learn/python/comparison-operators-python) — The boolean logic behind every case check.
- [Functions in Python in Depth](https://app.sythra.ai/learn/python/python-functions-in-depth) — Functions as values — what makes dictionary dispatch work.
- [Python course hub](https://app.sythra.ai/learn/python) — All free Python explainers and the path into Agentic practice.
- [Try/Except and Exception Handling in Python](https://app.sythra.ai/learn/python/try-except-python) — Catching errors gracefully with try, except, else, finally.

---

Written by Sythra — Learn machine learning by building. Practice this topic with Sythra's AI tutor: https://app.sythra.ai/pricing
