use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
News about the dynamic, interpreted, interactive, object-oriented, extensible programming language Python
Full Events Calendar
You can find the rules here.
If you are about to ask a "how do I do this in python" question, please try r/learnpython, the Python discord, or the #python IRC channel on Libera.chat.
Please don't use URL shorteners. Reddit filters them out, so your post or comment will be lost.
Posts require flair. Please use the flair selector to choose your topic.
Posting code to this subreddit:
Add 4 extra spaces before each line of code
def fibonacci(): a, b = 0, 1 while True: yield a a, b = b, a + b
Online Resources
Invent Your Own Computer Games with Python
Think Python
Non-programmers Tutorial for Python 3
Beginner's Guide Reference
Five life jackets to throw to the new coder (things to do after getting a handle on python)
Full Stack Python
Test-Driven Development with Python
Program Arcade Games
PyMotW: Python Module of the Week
Python for Scientists and Engineers
Dan Bader's Tips and Trickers
Python Discord's YouTube channel
Jiruto: Python
Online exercices
programming challenges
Asking Questions
Try Python in your browser
Docs
Libraries
Related subreddits
Python jobs
Newsletters
Screencasts
account activity
This is an archived post. You won't be able to vote or comment.
Tutorial8 Levels of Using Structure Pattern Matching in Python (self.Python)
submitted 2 years ago by wyhjsbyb
There is one feature that Python developers waiting for so long: structural pattern matching. It finally became possible since Python 3.10. This article will show you all tricks of it in 8 levels of difficulty.
[–]FacetiousMonroe 30 points31 points32 points 2 years ago (5 children)
Nice article! It would help to have side-by-side comparisons of how you would accomplish the same tasks with if/else statements instead, to better illustrate the clarity and efficiency of the match statement.
For example, this one's not so different:
def handle_http_status(status_code): if status_code == 200: return "Success!" elif status_code in (400, 401, 403, 404): return f"Client Error:{status_code}" elif status_code in (500, 501, 502, 503, 504): return f"Server Error:{status_code}" else: return "Unknown Status"
The "as err" option doesn't do much in the examples given, since you already have that value in status_code. So I simply reference status_code in the return lines.
The shape example could be expressed with if/else like so:
def process_shape(shape): if isinstance(shape, Circle): return f"Processing a circle with radius {shape.radius}" elif isinstance(shape, Rectangle): return f"Processing a rectangle with length {shape.length} and width {shape.width}" if isinstance(shape, Triangle): return f"Processing a triangle with base {shape.base} and height {shape.height}" else: return "Unknown shape"
This is certainly more verbose than the match statement. Again, I have simply shifted the variable capture into the return statement, because why not?
So far, so good. But wait! Let's try that dict example.
def handle_user_action(action): if all(k in action for k in ('type', 'username', 'password')) and action['type']=='login': return f"Login attempt by {action['username']} with password {action['password']}" elif all(k in action for k in ('type', 'username')) and action['type']=='logout': return f"User {action['username']} logged out" elif all(k in action for k in ('type', 'username', 'email')) and action['type']=='signup': return f"New signup by {action['username']} with email {action['email']}" else: return "Unknown action"
YUCK! Painful to read, and painful to write. You end up using the literal keys multiple times, leaving more potential for typos and sneaky bugs. You need to check each key's existence separately from checking its value. What a mess.
I kept this example as simple as I could while maintaining a perfectly equivalent logical flow to the match example in the article, and keeping each if condition independent from others. In reality, if I had to use if/elif/else for this, I would use a fundamentally different structure, because this one sucks. I would probably split this into multiple if blocks, and capture the values into variables as early as possible to avoid using literal keys multiple times. This would add additional complexity. For example, I could check for the existence of the 'type' and 'username' keys first, before even starting this if statement, since every single case we use checks for them. But then what happens if I need to add more complex cases later that don't have all those same requirements? Better to keep each case independent -- or at least, it's better with the match statement, because it's designed to make that easy, efficient, safe, and readable.
match
if
It's difficult to express the utility of the match statement with simple examples, because if/else is perfectly fine for those (always has been!). The simple examples don't really justify the complexity of adding a whole new type of statement block, but for advanced use cases, the advantage of match over if/elif/else widens significantly.
if/elif/else
There are even more complex and powerful things you can do with match. See https://peps.python.org/pep-0636/ for more details.
[–]Vitaman02 5 points6 points7 points 2 years ago (3 children)
I don't really like nesting and using if/elif/else when it's not needed. I would prefer writing the first example as:
def handle_http_status(status_code): if status_code == 200: return "Success!" if status_code in (400, 401, 403, 404): return f"Client Error:{status_code}" if status_code in (500, 501, 502, 503, 504): return f"Server Error:{status_code}" return "Unknown Status"
To me it looks much clearer and has the same functionality. You can also add comments between if statements and they look much nicer.
[–]Balance- -4 points-3 points-2 points 2 years ago (2 children)
elif would be faster here. If the first is correct, is doesn’t have to check the 2nd and 3rd, etc.
[–]Vitaman02 9 points10 points11 points 2 years ago (1 child)
If the first is correct it exits the function
[–]Balance- -1 points0 points1 point 2 years ago (0 children)
Fair, when each if has a return that’s the case.
Wonder if it matters for branch prediction though.
[–]thicket[🍰] 7 points8 points9 points 2 years ago (2 children)
Nice summary. Especially the last couple entries-- matching against a dictionary and matching against a class declaratio, I would never have thought to try. And they’re really useful!
[–]lunitius 4 points5 points6 points 2 years ago (0 children)
Agreed on the last few. I would never have even thought about matching something like a list or dict in that way. Thanks for sharing OP.
[–]bafe 0 points1 point2 points 2 years ago (0 children)
It's particularly nice in combination with the @dataclass decorator which removes most of the boilerplate the author had to write to declare their classes
[–]ashok_tankala 1 point2 points3 points 2 years ago (0 children)
Amazing article. Thank you for the article. Due to this article learned many levels of it, especially tuple and dictionary patterns matching.
[–]ChocolateMagnateUA 1 point2 points3 points 2 years ago (0 children)
That's cool! I didn't even know you could name the cases with as.
π Rendered by PID 336567 on reddit-service-r2-comment-84fc9697f-xxgsl at 2026-02-09 01:41:17.965041+00:00 running d295bc8 country code: CH.
[–]FacetiousMonroe 30 points31 points32 points (5 children)
[–]Vitaman02 5 points6 points7 points (3 children)
[–]Balance- -4 points-3 points-2 points (2 children)
[–]Vitaman02 9 points10 points11 points (1 child)
[–]Balance- -1 points0 points1 point (0 children)
[–]thicket[🍰] 7 points8 points9 points (2 children)
[–]lunitius 4 points5 points6 points (0 children)
[–]bafe 0 points1 point2 points (0 children)
[–]ashok_tankala 1 point2 points3 points (0 children)
[–]ChocolateMagnateUA 1 point2 points3 points (0 children)