Python match-case: Pattern Matching Explained

Updated on: May 30, 2026
Reading time: 4 minutes
Pattern matching com match case em Python

Python development has always been guided by readability and simplicity. With the release of version 3.10, the community received one of the most impactful updates in a decade: the introduction of Structural Pattern Matching, commonly known as match-case. If you have used switch-case structures in languages like C++ or Java, you might think match-case is just the syntactic equivalent — but it goes much further. This article explains how this feature revolutionizes the way we write logical flows, making code cleaner and less error-prone.

What is match-case and why is it special?

The match-case is a control flow structure that allows you to compare an object against multiple patterns in a declarative way. Before its arrival, programmers relied exclusively on if, elif, and else for multiple checks. While if is functional, it can become confusing and hard to maintain when dealing with complex type or structure checks.

The key difference from a traditional switch is that match-case does not just compare simple values (like numbers or strings) — it can also extract data from sequences, dictionaries, and even custom classes. This is called destructuring. Instead of asking “is this variable equal to X?”, you can ask “is this variable a two-element list where the second element is a number greater than ten?” This flexibility brings Python to a new level of expressiveness, approaching functional languages like Haskell and Scala.

Basic syntax: replacing if elegantly

status_code = 404

match status_code:
    case 200:
        print("Success!")
    case 404:
        print("Page not found.")
    case 500:
        print("Internal server error.")
    case _:
        print("Unknown status code.")

The underscore (_) acts as a wildcard. It captures any value not matched by the earlier cases — the equivalent of a final else in an if-elif chain. It is good practice to always include a wildcard case to avoid unexpected behavior.

Matching multiple values in one case

The | operator works as a logical OR inside a pattern, grouping values that should trigger the same action:

command = "EXIT"

match command.lower():
    case "help" | "info" | "?":
        print("Showing help menu...")
    case "exit" | "quit" | "q":
        print("Shutting down the program.")
    case _:
        print("Unknown command.")

Destructuring sequences: lists and tuples

The real magic of match-case appears when dealing with collections. Python can automatically unpack a list and assign its elements to named variables:

action = ["move", "north", 10]

match action:
    case ["stop"]:
        print("Character stopped.")
    case ["move", direction]:
        print(f"Moving {direction} at default speed.")
    case ["move", direction, speed]:
        print(f"Moving {direction} at {speed} km/h.")
    case _:
        print("Unknown action.")

This eliminates the need to access indices manually (e.g. action[1]), which often triggers an IndexError if the programmer forgets to check the list length first.

Combining patterns with guards

Sometimes pattern matching alone is not enough. You can add an extra logical check on the captured variables using a guard: an if clause right after the case pattern.

coordinate = (10, 50)

match coordinate:
    case (x, y) if x == y:
        print(f"Point is on the diagonal at {x}.")
    case (x, y) if y > 0:
        print(f"Point ({x}, {y}) is in the upper half of the plane.")
    case (x, y):
        print(f"Point is at ({x}, {y}).")

Matching dictionaries

If you work with APIs you likely deal with JSON data that becomes Python dictionaries. Match-case makes it easy to extract specific keys without breaking if a key is missing:

user = {"name": "Alice", "role": "Admin", "access": 5}

match user:
    case {"role": "Admin", "name": name}:
        print(f"Welcome, admin {name}!")
    case {"name": name}:
        print(f"Hello, regular user: {name}")

When matching dictionaries, Python checks that the specified keys exist. If the pattern is {"role": "Admin"}, the match succeeds even if the dictionary has extra keys like “access”. This is extremely useful for quickly validating data schemas.

Pattern matching with dataclasses

from dataclasses import dataclass

@dataclass
class Order:
    item: str
    quantity: int
    priority: bool

current_order = Order("Keyboard", 2, True)

match current_order:
    case Order(item, qty, True):
        print(f"URGENT: Ship {qty} units of {item} immediately.")
    case Order(item, qty, False) if qty > 10:
        print(f"Stock: Prepare large shipment of {item}.")
    case Order(item):
        print(f"Normal order received for {item}.")

Advantages over traditional if-elif

Match-case offers better readability because code describes the expected data shape rather than just logical operations. It also increases safety by reducing errors from accessing non-existent indices in Python lists, and improves expressiveness by handling multiple Python data types in a combined and elegant way. According to the Python Software Foundation, this structure was designed to be robust and replace complex data filtering patterns.

Frequently Asked Questions

Is match-case faster than if-elif-else?

For everyday use cases the performance difference is negligible. For large decision structures, match-case may be slightly more efficient due to how the interpreter optimizes the pattern search tree.

Can I use match-case in Python 3.8 or 3.9?

No. This feature was introduced exclusively in Python 3.10. Running this code on earlier versions produces a syntax error.

What happens if no case is matched?

If no pattern is found and there is no wildcard case (case _), the match block ends without executing any action and the program continues to the next line after the block.

Can I use complex expressions inside a case?

Patterns in case must be structural patterns or constant values. For complex logic, use guards — the if clause after the pattern — where almost any Python boolean expression is allowed.

Can I nest match-case blocks?

Yes, you can place a match block inside a case of another match. Be careful not to over-indent, as that can hurt readability.

Does match-case replace dictionary-based function mapping?

In some cases yes, but dictionary mapping (where keys point to functions) is still a valid and very fast technique for simple selections based on a single key.

Share:

Facebook
WhatsApp
Twitter
LinkedIn

Article content

    Related articles

    Como resolver loop infinito que nunca termina em Python
    Fundamentals
    Foto de perfil de Leandro Hirt da Academify

    Why Does My Loop Never End? Find the Solution

    Find out why your Python loop never ends and learn how to fix infinite loops caused by missing increments, wrong

    Ler mais

    Tempo de leitura: 6 minutos
    29/05/2026
    Logo do Python com as palavras global e local
    Fundamentals
    Foto de perfil de Leandro Hirt da Academify

    Python Variable Scope Explained Clearly

    Learn Python variable scope with clear examples of local, global, enclosing, built-in scope, LEGB rules, global, nonlocal, and common mistakes.

    Ler mais

    Tempo de leitura: 9 minutos
    28/05/2026
    Comparativo dos melhores cursos de Python para aprender programação
    Fundamentals
    Foto de perfil de Leandro Hirt da Academify

    8 Best Python Courses for Beginners in 2026

    Compare the 8 best Python courses for beginners in 2026, including Academify, Alura, Udemy, Coursera, Codecademy, Harvard CS50, EBAC, and

    Ler mais

    Tempo de leitura: 7 minutos
    28/05/2026
    Como usar f-strings para formatar números e moedas em Python
    Fundamentals
    Foto de perfil de Leandro Hirt da Academify

    Python f-strings: Format Numbers and Currency

    Learn how to use Python f-strings to format numbers, currency, percentages, alignment, and zero-padding with clean and practical examples.

    Ler mais

    Tempo de leitura: 6 minutos
    28/05/2026
    Uso do operador ternário em Python para condições rápidas
    Fundamentals
    Foto de perfil de Leandro Hirt da Academify

    Python Ternary Operator: Clean One-Line If

    Learn how Python ternary operators work, when to use one-line if expressions, how to avoid nested logic, and how to

    Ler mais

    Tempo de leitura: 8 minutos
    21/05/2026
    Logo lambda usado no Half-Life
    Fundamentals
    Foto de perfil de Leandro Hirt da Academify

    Python Lambda Functions Explained Clearly

    Learn Python lambda functions with clear examples, syntax, sorting, map, filter, closures, common mistakes, and when to prefer def.

    Ler mais

    Tempo de leitura: 8 minutos
    21/05/2026