The match Statement in Python
The match statement compares one value against a series of case patterns and runs the block of the first pattern that fits. It arrived in Python 3.10 and is the closest thing Python has to the switch statement of other languages, with case _: as the default.
Key facts
matchneeds Python 3.10 or newer. On older versions it is a syntax error.- Only the first matching
caseruns. Python never falls through to the next case, so no case needs abreak. case _:matches anything, so it is the default and it goes last.- One
casecan list several values with|, and anifafter the pattern adds a condition.
Does Python have a switch statement?
Not by that name, but since Python 3.10 the match statement does the same job. Write match and the value, then one case per pattern with an indented block. Python tries the cases from the top and runs the first one that fits.
status = 404
match status:
case 200:
print("OK")
case 404:
print("Not found")
case 500:
print("Server error")
case _:
print("Unknown status")Not found
Before 3.10 the same job needed an if / elif chain or a dictionary lookup, which a later lesson shows, and both still work. match reads better once there are more than three or four alternatives.
What is case _ in Python?
The wildcard. An underscore pattern matches any value, so case _: is the default branch, and it has to be the last case because nothing after it could ever run.
How do I match multiple values in one case?
Separate them with |. The case matches when the value equals any one of them, which replaces a chain of or comparisons. Inside a case pattern, | means or. It is not the bitwise operator from the logical operators lesson.
day = "sun"
match day:
case "sat" | "sun":
print("Weekend")
case "mon" | "tue" | "wed" | "thu" | "fri":
print("Weekday")
case _:
print("Not a day")Weekend
Can a match case have a condition?
Yes. Add if and a condition after any pattern, and the case matches only when the condition is also true. That if is called a guard, and it is how match handles ranges. To use the value inside the guard, write a new name such as t as the pattern. It matches any value and stores it in t.
temperature = 32
match temperature:
case t if t < 10:
print("Cold")
case t if t < 25:
print("Mild")
case t:
print(f"Hot, {t} degrees")Hot, 32 degrees
The last case has no condition, so it catches everything else and keeps the value in t.
Does match fall through like a switch?
No. In C and JavaScript, a switch keeps running into the next case, called fall-through, until a break stops it. In Python at most one case runs, the first one that matches, and then the statement is over, so no case needs a break and there is none to forget. A second case with the same value is never reached.
command = "start"
match command:
case "start":
print("Starting")
case "start":
print("Never printed, the first case already matched")
case _:
print("Unknown")
print("Only one case ran, no break needed")Starting Only one case ran, no break needed
Can match unpack a tuple or list?
Yes, and that is where it beats if. A pattern can describe the shape of a tuple or list and pull the parts out into names in the same line.
point = (0, 5)
match point:
case (0, 0):
print("Origin")
case (0, y):
print(f"On the y axis at {y}")
case (x, 0):
print(f"On the x axis at {x}")
case (x, y):
print(f"At {x}, {y}")On the y axis at 5
Dictionaries and class instances have patterns of their own too. Those patterns are easier to follow after the dictionaries and classes lessons later in the course.
Is match better than if and elif?
For one value against several exact alternatives, or for taking a value apart, yes. For a couple of conditions, or for conditions that compare different variables, if / elif is shorter and clearer. Like an elif chain, match tries its cases one at a time from the top, so the choice is about reading, not speed.
Common mistakes with match in Python
These four mistakes with match are one version problem, two pattern problems and one name mix-up.
- SyntaxError: invalid syntax on the match line. The Python running the file is older than 3.10. Check with
python --version, orpython3 --versionon macOS and Linux. - SyntaxError: name capture 'x' makes remaining patterns unreachable. A plain name with no guard matches everything, so it must be the last case, like
_. - Expecting a case to compare with a variable.
case RED:does not compare with a variable namedRED. It captures the value intoREDand replaces what was there. Compare in a guard instead.case c if c == RED:matches when the value equalsRED. - Confusing it with
re.match(). That is a function for regular expressions and has nothing to do with the statement.
color = "red"
match color:
case anything:
print("first")
case "red":
print("red") File "main.py", line 3
case anything:
^^^^^^^^
SyntaxError: name capture 'anything' makes remaining patterns unreachableExercise
The program prints nothing for "sat", because only weekdays have a case. Add one case that matches both "sat" and "sun" and prints Weekend.
day = "sat"
match day:
case "mon" | "tue" | "wed" | "thu" | "fri":
print("Weekday")
Weekend
Show the solution
day = "sat"
match day:
case "mon" | "tue" | "wed" | "thu" | "fri":
print("Weekday")
case "sat" | "sun":
print("Weekend")
Quiz
This quiz has 5 questions. Pick an answer to see why it is right or wrong.
-
1What does this program print?
n = 2 match n: case 1 | 2 | 3: print("small") case _: print("other")The | pattern matches any of the listed values, and only the first matching case runs.
-
2What does case _: do?
The underscore is the wildcard pattern. It matches any value, so it works as the default and must be the last case, or Python reports a SyntaxError.
-
3Which Python version introduced match?
Structural pattern matching, the feature behind the match statement, arrived in Python 3.10 in October 2021. Older versions report a syntax error.
-
4Do you need break at the end of each case?
match never falls through to the next case. Only the first matching case runs, so no case needs a break.
-
5What does this program print?
p = (3, 0) match p: case (0, y): print("y axis") case (x, 0): print("x axis")(0, y) needs a first element of 0, which fails. (x, 0) needs a second element of 0, which fits.