You can define a default case in Python. For this you use a wild card (_). The following code demonstrates it:

x = "hello"
match x:
    case "hi":
        print(x)
    case "hey":
        print(x)
    case _:
        print("not matched")
Answer from Prince Hamza on Stack Overflow
🌐
Plain English Westminster
benhoyt.com › writings › python-pattern-matching
Structural pattern matching in Python 3.10
Python evaluates the match expression, and then tries each case from the top, executing the first one that matches, or the _ default case if no others match. But here’s where the structural part comes in: the case patterns don’t just have to be literals.
🌐
Python
peps.python.org › pep-0622
PEP 622 – Structural Pattern Matching | peps.python.org
In deciding what names should be ... names and their types should resemble the arguments to __init__(). Only match-by-name will work by default, and classes should define __match_args__ as a class attribute if they would like ...
🌐
Real Python
realpython.com › structural-pattern-matching
Structural Pattern Matching in Python – Real Python
August 6, 2024 - If the provided operator isn’t defined in the dictionary, then you default to a lambda expression that always returns None. This method lets you extend the dictionary with additional operators if necessary.
🌐
LabEx
labex.io › tutorials › python-how-to-define-default-case-in-matching-418555
How to define default case in matching | LabEx
Pattern matching is a powerful feature introduced in Python 3.10 that provides a more concise and readable way to handle complex conditional logic. Unlike traditional if-elif-else statements, pattern matching allows developers to match values against different patterns with greater flexibility. def match_example(value): match value: case pattern1: ## Action for pattern1 return result1 case pattern2: ## Action for pattern2 return result2 case _: ## Default case (catch-all) return default_result
🌐
Python documentation
docs.python.org › 3 › library › re.html
re — Regular expression operations — Python 3.14.3 ...
The letters 'a', 'L' and 'u' are mutually exclusive when used as inline flags, so they can’t be combined or follow '-'. Instead, when one of them appears in an inline group, it overrides the matching mode in the enclosing group. In Unicode patterns (?a:...) switches to ASCII-only matching, and (?u:...) switches to Unicode matching (default).
🌐
Python
peps.python.org › pep-0636
PEP 636 – Structural Pattern Matching: Tutorial | peps.python.org
The match statement will check patterns from top to bottom. If the pattern doesn’t match the subject, the next pattern will be tried. However, once the first matching pattern is found, the body of that case is executed, and all further cases are ignored.
🌐
Python
peps.python.org › pep-0635
PEP 635 – Structural Pattern Matching: Motivation and Rationale | peps.python.org
There is a subtle reason for using get(key, default) instead of __getitem__(key) followed by a check for AttributeError: if the subject happens to be a defaultdict, calling __getitem__ for a non-existent key would add the key.
Find elsewhere
🌐
Python documentation
docs.python.org › 3 › whatsnew › 3.10.html
What’s New In Python 3.10
If an exact match is not confirmed and a wildcard case does not exist, the entire match block is a no-op. Readers may be aware of pattern matching through the simple example of matching a subject (data object) to a literal (pattern) with the switch statement found in C, Java or JavaScript (and many other languages).
🌐
Stackademic
blog.stackademic.com › python-match-case-statement-63d01477e1c0
Python Match-Case Statement. Starting from Python 3.10, the Python… | by Caner Uysal | Stackademic
June 12, 2024 - Partial Matching: Python’s match statement allows for defining a fallback (default) case using “_” (underscore) for cases where patterns do not match exactly. This allows handling values that do not match any of the specified patterns.
🌐
Mathspp
mathspp.com › blog › pydonts › structural-pattern-matching-tutorial
Structural pattern matching tutorial | Pydon't 🐍 | mathspp
__match_args__ allows to define a default order for arguments to be matched in when a custom class is used in a case · built-in Python classes can be used in case statements to validate types
🌐
W3Schools
w3schools.com › python › python_match.asp
Python Match
The value _ will always match, so it is important to place it as the last case to make it behave as a default case.
🌐
GeeksforGeeks
geeksforgeeks.org › python-match-case-statement
Python Match Case Statement - GeeksforGeeks
December 18, 2024 - _ (Wildcard): A default catch-all pattern, similar to a "default" in other languages' switch statements. Now, let us see a few examples to know how the match case statement works in Python.
🌐
InfoWorld
infoworld.com › home › software development › programming languages › python
How to use structural pattern matching in Python | InfoWorld
August 9, 2023 - That said, enums tend to be the most familiar and idiomatic way to do this in Python. You cannot match against variable contents through indexing. For instance, case commands[0]: would be rejected as a syntax error. The key to working most effectively with pattern matching is not just to use it as a substitute for a dictionary lookup or an if/else chain.
Top answer
1 of 4
22

This is a common "gotcha" of the new syntax: case clauses are not expressions. That is, if you put a variable name in a case clause, the syntax assigns to that name rather than reading that name.

It's a common misconception to think of match as like switch in other languages: it is not, not even really close. switch cases are expressions which test for equality against the switch expression; conversely, match cases are structured patterns which unpack the match expression. It's really much more akin to generalized iterable unpacking. It asks the question: "does the structure of the match expression look like the structure of the case clause?", a very different question from what a switch statement asks.

For example:

t = 12.0
match t:
    case newvar: # This is equal to `newvar = t`
        print(f"bound a new variable called newvar: {newvar}")
        # prints "bound a new variable called newvar: 12.00000000"
        # this pattern matches anything at all, so all following cases never run

    case 13.0:
        print("found 13.0")

    case [a, b, c]: # matches an iterable with exactly 3 elements,
        # and *assigns* those elements to the variables `a`, `b` and `c`
        print(f"found an iterable of length exactly 3.")
        print(f"these are the values in the iterable: {a} {b} {c}")

    case [*_]:
        print("found some sort of iterable, but it's definitely")
        print("not of length 3, because that already matched earlier")

    case my_fancy_type(): # match statement magic: this is how to type check!
        print(f"variable t = {t} is of type {my_fancy_type}")

    case _:
        print("no match")

So what your OP actually does is kinda like this:

t = 12.0
tt = type(t) # float obviously
match tt:

    case int: # assigns to int! `int = tt`, overwriting the builtin
       print(f"the value of int: {int}")
       # output: "the value of int: <class 'float'>"
       print(int == float) # output: True (!!!!!!!!)
       # In order to get the original builtin type, you'd have to do
       # something like `from builtins import int as int2`

    case float: # assigns to float, in this case the no-op `float = float`
        # in fact this clause is identical to the previous clause:
        # match anything and bind the match to its new name
        print(f"match anything and bind it to name 'float': {float}")
        # never prints, because we already matched the first case

    case float(): # since this isn't a variable name, no assignment happens.
        # under the hood, this equates to an `isinstance` check. 
        # `float` is not an instance of itself, so this wouldn't match.
        print(f"tt: {tt} is an instance of float") # never prints
        # of course, this case never executes anyways because the
        # first case matches anything, skipping all following cases

Frankly, I'm not entirely sure how the under-the-hood instance check works, but it definitely works like the other answer says: by defintion of the match syntax, type checks are done like this:

match instance:
    case type():
        print(f"object {instance} is of type {type}!")

So we come back to where we started: case clauses are not expressions. As the PEP says, it's better to think of case clauses as kind of like function declarations, where we name the arguments to the function and possibly bind some default values to those newly-named arguments. But we never, ever read existing variables in case clauses, only make new variables. (There's some other subtleties involved as well, for instance a dotted access doesn't count as a "variable" for this purpose, but this is complicated already, best to end this answer here.)

2 of 4
17

Lose the type() and also add parentheses to your types:

t = 12.0
match t:
  case int():
    print("int")
  case float():
    print("float")

I'm not sure why what you've wrote is not working, but this one works.

🌐
LabEx
labex.io › tutorials › python-how-to-create-default-case-in-match-418553
How to create default case in match | LabEx
Python 3.10 introduced the match statement, a powerful pattern matching feature that provides a more expressive and concise way to handle complex conditional logic. Unlike traditional if-elif-else structures, match allows for more sophisticated pattern matching. def example_match(value): match value: case pattern1: ## Action for pattern1 return result1 case pattern2: ## Action for pattern2 return result2 case _: ## Default case (catch-all) return default_result
🌐
ArjanCodes
arjancodes.com › blog › how-to-use-structural-pattern-matching-in-python
Introduction to Structural Pattern Matching in Python | ArjanCodes
June 20, 2024 - The __match_args__ attribute is a tuple that specifies the attribute names for pattern matching. By default, it’s an empty tuple, meaning no attributes can be extracted.
🌐
Better Stack
betterstack.com › community › guides › scaling-python › python-pattern-matching
Structural Pattern Matching in Python: A Comprehensive Guide | Better Stack Community
Learn how to use structural pattern matching in Python to simplify complex conditionals and make your code more readable. This guide covers matching with basic types, dictionaries, guard clauses, and more—introduced in Python 3.10 and enhanced in Python 3.13.
🌐
JetBrains
jetbrains.com › help › pycharm › pattern-matching.html
Pattern matching | PyCharm Documentation
For more information about examples and use cases, refer to the feature overview at docs.python.org and PEP-636 (tutorial). PyCharm provide the following coding assistance for pattern matching: ... PyCharm supports parsing and highlighting of the matching syntax. To alter the default code styles, ...