Literal Pattern
Structural Pattern Matching is a powerful replacement for if/elif/else and the easiest way to get started with that is by matching a single value:
import random
match random.randint(0, 10):
case 5:
print("Lucky!")In this case we’re going to match against the output of random.randint(0, 10) with all different match cases and it is executed from top to bottom.
Or Pattern
Let’s add a new case by using the Or Pattern:
match random.randint(0, 10):
case 5:
print("Lucky!")
case 4 | 6:
print("You got close!")Capture Pattern
When we got “You got close” we don’t know if 4 or 6 is chosen, so let’s add another piece of syntax to let us know which one we actually got:
match random.randint(0, 10):
case 5:
print("Lucky!")
case 4 | 6 as num:
print(f"You got close with {num}!")In this case, as numis going to capture whichever one of those matched and store that random number into this variable.
Now let’s cover case where we didn’t hit 5, 4 or 6 specifically we want to see if we got at least an odd number:
match random.randint(0, 10):
case 5:
print("Lucky!")
case 4 | 6 as num:
print(f"You got close with {num}!")
case num if num % 2 != 0:
print(f"at least {num} was odd.")Note that:
- the
ifstatement in the structural pattern matching language is called Guard. In this case it tries to match against anything, but guarded with a condition. - if we remove the
ifstatement in the last case clause, we got the so-called Capture Pattern becausenumit’s going to match against anything.
Wildcard Pattern
The last common pattern is called Wildcard, represented by _, that is going to match everything again except we’re not going to put any guards on it and it doesn’t bind to a variable:
match random.randint(0, 10):
case 5:
print("Lucky!")
case 4 | 6 as num:
print(f"You got close with {num}!")
case num if num % 2 != 0:
print(f"at least {num} was odd.")
case _:
print("You missed!")Actually, if you do care about this last case and don’t want to just have a blank wildcard to fall back to, you can still have that wildcard behaviour and you can handle this in this way:
match random.randint(0, 10):
case 5:
print("Lucky!")
case 4 | 6 as num:
print(f"You got close with {num}!")
case num if num % 2 != 0:
print(f"at least {num} was odd.")
case _ as miss: # or simply "case miss:"
print(f"You missed with {miss}!")or simply case miss: instead of case _ as miss:.
What happens if we add the wildcard pattern as last case match? The IDE marks case miss: as a error saying “Irrefutable pattern is allowed only for the last case statement” and that’s because we have two cases case miss and case _ that match everything:
match random.randint(0, 10):
case 5:
print("Lucky!")
case 4 | 6 as num:
print(f"You got close with {num}!")
case num if num % 2 != 0:
print(f"at least {num} was odd.")
case miss:
print(f"You missed with {miss}!")
case _:
print("Fail")This could be a good way for us to check to make sure tat we don’t have cases within our patterns that are going to be more general than you’re expecting. For example, we would have the same error with this code:
match random.randint(0, 10):
case 5:
print("Lucky!")
case 4 | 6 as num:
print(f"You got close with {num}!")
case miss:
print(f"You missed with {miss}!")
case num if num % 2 != 0:
print(f"at least {num} was odd.")Matching structured data
TODO: to finish