Introducing Structural Pattern Matching
00:00 Before we get to the exciting action of using structural pattern matching, you’ll want to familiarize yourself with its terminology and syntax. Structural pattern matching was added to the language in Python 3.10.
00:12
It makes use of three new soft keywords: match
, case
and _
, which is used as a wild card. Now, soft keyword is kind of a new concept.
00:22 They’re a little bit different from other Python keywords because they’re contextual. Outside of their keyword context, they’re considered valid variable names.
00:30
But to minimize confusion, I do recommend treating them like any other keyword. With structural pattern matching, you can write clean declarative control flows without using if
else
.
00:41 What does declarative mean? You’ll see in an example soon, but it’s essentially a programming style that is focused on describing what your code should do rather than how it should be done.
00:51 In contrast, code that focuses on how is called imperative. Lastly, structural pattern matching is based on applying two key concepts: structural patterns, and pattern matching.
01:02 This is what the rest of the lesson is about. First, let’s look at structural patterns.
01:08 There are several kinds of structural patterns available in Python. Structural patterns can describe an object by its type, its value, its shape, its identity, or getting more complex here, its constituent elements and this can be done via object deconstruction, which is also called destructuring.
01:26 Destructuring is not new to Python. You’ve probably used it yourself.
01:31
Here are a few of the ways that Python supported object deconstruction prior to the introduction of pattern matching. You can unpack Python iterable using iterable unpacking and the star operator, for example, head, *
middle, tail = range(10)
.
01:46
This stores the first element of the range in head
, the last tail
and the remaining elements in middle
. You can use object deconstruction to unpack and merge dictionaries.
01:56
A dictionary literal with the contents **headers
**cookies
unpacks the headers
and cookies
dictionaries, and creates a new dictionary with the keys and values of both.
02:06
Using square bracket accessor, you can access items by position or index in sequence types like pulling out last item from the items
list by accessing the element at index -1
.
02:18
Or you can access items by key in mapping types like dictionaries, pulling out path
from os.environ
at the key path
.
02:25
Finally, accessing attributes of an object by their name can be done via the dot accessor like getting date
from datetime.date
.
02:33 You’ll soon see that structural pattern matching in Python continues to build on this concept of deconstruction, allowing you to match complex and very specific data structures.
02:43 So those are structural patterns. What about pattern matching?
02:47
match
takes a subject, case
introduces a pattern to compare against. See this example. It may seem complicated right now, but by the end of this course you’ll be able to write patterns like this with ease: match subject:
case [int | float as x,
int | float as y, 0]:
03:12
print()
, with the values of x and y interpolated inside a pair of parentheses.
03:19
Subject here can be any valid expression in Python, and this specific pattern defined by case
will match a list of two numerics, and a third element equal to zero.
03:30 Think about how you could implement the same behavior without pattern matching.
03:35 On the left hand side we have our previous example, and on the right hand side we have one way you could perform the same matching without using patterns.
03:43
if isinstance(subject, list)
and len(subject) == 3
, if isinstance(subject[0], (int, float))
, and isinstance(subject[1], (int, float))
, and subject[2] == 0:
,
04:03
x, y, _ = subject
and print(f"Point({x}, {y})")
.
04:10
Note that in this case the underscore used in unpacking subject
is a common Python idiom indicating that whatever the contents of the underscore variable, it won’t be used in the rest of the program.
04:21 This is distinct from how you’ll see the character being used in future lessons.
04:25 So comparing these two different styles, you can see our pattern matching code is very concise and very declarative. You simply describe the kind of object you’d like to match as a pattern, and Python handles the rest.
04:37
Without pattern matching, the code is verbose to say the least. It’s a little hard to read, and it’s also imperative. You define exactly how to match subject
through repeated if
conditions.
04:50 Now, imperative isn’t always wrong and declarative isn’t always right, but I know in this case which style I would prefer to use. So generally, when should you use structural pattern matching?
05:03 Structural pattern matching is ideal for situations where data structures are complex or nested, decisions are made based on parts of the data using destructuring, patterns to match are largely exclusive of each other, and conditions are not based on complex business rules requiring lots of computation or many calculations at runtime.
05:23 Congratulations, you made it through the theory and now it’s time for the practice. In the next lesson, we’ll introduce a few basic patterns and get started on a project to see them in action.
Become a Member to join the conversation.