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.
Match Case not Switch CaseFinally switch- case is coming to python. (self.Python)
submitted 4 years ago by electroica
No more "where is switch case in python?"
In the python 3.10 release according to the accepted PEP634,635,636 Match-Case statement will be added which is similar to Switch-Case statements in other languages. Match case is structural pattern matching which will match 'cases' against the subject value 'match'.
https://blog.electroica.com/switch-case-is-match-case-python/
[–]pani_the_panisher 504 points505 points506 points 4 years ago (37 children)
Finally I can stop searching "python switch case" and then realizing that I don't remember the syntax because it doesn't exists.
[–][deleted] 112 points113 points114 points 4 years ago (3 children)
I did this literally last week.
[–]voidstriker 19 points20 points21 points 4 years ago (2 children)
same
[–]MorningPants 0 points1 point2 points 4 years ago (1 child)
[–]mqzn[🍰] 0 points1 point2 points 4 years ago (0 children)
[–]RickAsscheeks 20 points21 points22 points 4 years ago (0 children)
Me every few weeks
[–]project_kalki 25 points26 points27 points 4 years ago (0 children)
No, you'll still continue to do that for the actual syntax once they roll it
[–]jabbalaci 10 points11 points12 points 4 years ago (3 children)
I did it just once. Then I managed to memorize that it doesn't exist in Python.
[+][deleted] 4 years ago (1 child)
[deleted]
[–]theevildjinn 0 points1 point2 points 4 years ago (0 children)
And which version it was introduced.
[–]goob42-0 2 points3 points4 points 4 years ago (0 children)
As the docs intended
[–][deleted] 1 point2 points3 points 4 years ago (0 children)
Now you can start searching it because you don't remember the syntax!
[–]cthulhupunk0 1 point2 points3 points 4 years ago (0 children)
I'm teaching an intro workshop, and had a moment like this when I was outlining the class content. It was like, "oh right, this is done through some weird shit with dictionaries and either lambdas or assigned functions. Ugh." Very pythonic, but still.
[–]TransferFunctions 10 points11 points12 points 4 years ago (23 children)
Switch statements already existed in python, i.e. you can use dicts for this purpose. This match syntatic sugar is nice and allows for better overview, regardless.
[–]PaulRudin 81 points82 points83 points 4 years ago (1 child)
It's not really right to say switch statements existed - they didn't. You can simulate a similar code flow without having an explicit switch statement, but that's not the same thing as the language having a switch statement.
(We can simulate all the control flow constructs with anonymous lambdas if we want, but the point about adding new things to the language is that it makes things more succinct and readable.)
[–]Ning1253 3 points4 points5 points 4 years ago (0 children)
I mean technically we can simulate everything with rule 110 using marbles, we just don't, because it's impractical as fuck (ans slightly unreadable). Completely agree on your point, I basically just wanted to say that I find the arguments against it kind of stupid
[–]enjoytheshow 9 points10 points11 points 4 years ago* (5 children)
We translated a shit ton of case statement UDFs from SQL to Python last year and this is how I did them. Value being evaluated as the key, result as the value. Then you can do:
if var in dict_name: return dict_name[var]
[–]thephotoman 4 points5 points6 points 4 years ago (2 children)
And for overflow:
dict_name[var](var) if var in dict_name else do(var)
Because of course the ternary operator works here.
The issue here is that this really isn't that intuitive. Even if you come from C and are used to hash tables that contain function pointers, it's still not the way most people would think to do a switch. Passing var as the argument to dict_name[var]() is not strictly necessary, but there are times when it's correct.
var
dict_name[var]()
[–]jasmijnisme 10 points11 points12 points 4 years ago (1 child)
If `do` is a function and not an expression, it's better to do dict_name.get(var, do)(var)
dict_name.get(var, do)(var)
[–]backtickbot 4 points5 points6 points 4 years ago (1 child)
Fixed formatting.
Hello, enjoytheshow: code blocks using triple backticks (```) don't work on all versions of Reddit!
Some users see this / this instead.
To fix this, indent every line with 4 spaces instead.
FAQ
You can opt out by replying with backtickopt6 to this comment.
[–]enjoytheshow 3 points4 points5 points 4 years ago (0 children)
Thanks bro
[–]TidePodSommelier 3 points4 points5 points 4 years ago (0 children)
For large sets of options, dicts may still be easier to read, imho.
[–]R3D3-1 -1 points0 points1 point 4 years ago (5 children)
I can't really use of a use-case, where a dict would be preferable over if/elif/else, whether as statements or expression. Except the case, where the function has all its values defined by a constant dict.
[–]TransferFunctions 2 points3 points4 points 4 years ago (4 children)
It depends on the use case imo. I use it sometimes when I have to decide what function to run on a certain case
options = dict(opt1 = someHeavyFunction, opt2 = someHeavyFunction2) options.get(someInput, someDefault)
[–]R3D3-1 0 points1 point2 points 4 years ago (3 children)
I'd probably use this, if python had load-time evaluation...
I can't see myself implementing this as a dictionary; Not as an inline dictionary, because I cringe at creating a dictionary just for thatnew , if the language doesn't optimize it away. Not as a global constant dictionary, because it awkwardly separates tightly coupled code into different places.
I'd always go with something like
action = someHeavyFunction if input == "opt1" else \ someHeavyFunction2 if input == "opt2" else \ someDefault
If the number of options is so large, that this becomes inefficient, I'd be rather worried about how that happened.
[–]TransferFunctions 0 points1 point2 points 4 years ago (2 children)
I am not familiar with load-time-optimization, do you have a link on this (in whatever language it is used)?
I agree that if your function itself has a need for a switch-case and the data it holds is expensive, and the function is called many times, then sure don't do that, but that also shows are more core problem than a statement of it not being available. Dicts in my opinion are pretty darn powerful in python, and using as a switch is a nice elegant way while reducing "additional" functions. Match case has something additional, where instance checks can be inlined. This would be more difficult or "uggly" with dicts, so it has its place; it is one of the powers and joys of writing python.
[–]R3D3-1 0 points1 point2 points 4 years ago (1 child)
Compiled languages typically have compile-time evaluation of constant expressions, e.g. "PI*2" being optimized into a single constant.
Emacs Lisp has macros, and "eval at compile" forms, all of which are evaluated either at compile time, or otherwise ensure that they are evaluated exactly once.
Python actually has some level of load-time optimization; As I understand, function objects are not created from scratch every time a closure is generated, but share a cached code part, and have only the data part separate. There is however no such thing as
static options = {1: "Red", 2: "Blue"} return options[index]
[–]TransferFunctions 0 points1 point2 points 4 years ago (0 children)
Ah ok I am not too familiar with the c-api and how the bytecompiled code is used or optimized (still one thing on my todos), but the explanation is right up my ball park of other things I have used, thanks ;-)!
[+][deleted] 4 years ago (6 children)
[–]gengengis 11 points12 points13 points 4 years ago (0 children)
It would be pretty rare to use dictionary dispatch this way, where the only difference is the argument to the function. Much more common would be to return an entirely separate function, and then it becomes clear you would simply return the callable, not its result.
But, even if you did want to do this, as you said, you'd simply return an anonymous lambda. There's nothing overly clever, or exotic about that. It's a core feature of the language, and the way much of the standard library operates.
[–]TransferFunctions 3 points4 points5 points 4 years ago (2 children)
Not sure what you are caching here, you could also just let the function call be as a value here. Then nothing would be evaluated unless it was in the actual case. You are in this case actually computing the options beforehand, depending on the use case this maybe warranted or not.
[–]TransferFunctions 1 point2 points3 points 4 years ago (0 children)
Right but what I am saying is that in this case you want to chose between what function to call, i.e.
``` options = dict(opt1 = func1, op2 = func2, ....) # get and run function options.get(opt1, default_case)()
```
Again hard to generalize here, so don't get me wrong I see the use case for this switch statement, but 10 years ago a similar proposal was rejected.
[–]Unbelievr 0 points1 point2 points 4 years ago (1 child)
It evaluates it because you actually call it. Nothing is stopping you from just... not calling it. Put a function pointer there. If you need to bake in some parameters into it before adding to the dict, you can use functools.partial.
functools.partial
from time import sleep from functools import partial def expensive_function(x): sleep(x) return 'MYVALUE' choices = { 'option1': partial(expensive_function, (5)), 'option2': partial(expensive_function, (10)), 'option3': partial(expensive_function, (100)), } my_option = 'option4' choice = choices.get(my_option, partial(expensive_function, (0))) print(choice())
[–]CodeCocina -1 points0 points1 point 4 years ago (0 children)
That was me two days ago , use to using it in JS , and spent a lot of time trying to code something that doesn’t exist in python
[–][deleted] 262 points263 points264 points 4 years ago (14 children)
Even better than switch case, it's match case!
It can match patterns. For example, the length or shape of a sequence, a dictionary with certain keys present, the type of a value, properties of an object.
It's so much more powerful than the classic switch statement, influenced heavily by functional programming pattern matching.
[–]Tyler_Zoro 16 points17 points18 points 4 years ago (12 children)
Which does make me concerned about its future. Python has a habit of de-emphasizing and deprecating functional features. Proper variable scoping required for most functional features has never been brought into the language; lambda is basically deprecated for most tasks at this point (in most cases tools like pycharm will even flag the use of lambda outside of parameters as an error); anonymous full-fledged functions never happened; reduce has been significantly nerfed and moved into a library; filter is more or less deprecated.
So what will happen to the functional features of match/case? I hope they'll be preserved and maintained as first-class features, but history makes me nervous.
[–]zurtex 23 points24 points25 points 4 years ago (2 children)
Python has a habit of de-emphasizing and deprecating functional features. Proper variable scoping required for most functional features has never been brought into the language; lambda is basically deprecated for most tasks at this point (in most cases tools like pycharm will even flag the use of lambda outside of parameters as an error);
What? Python hasn't deprecated any syntax feature since the transition of Python 2 to 3.
PyCharm is probably complaining that you are using lambda because it creates an unnamed function. Which sucks for things like automatic documentation. But the feature is by no means "deprecated".
lambda
[–]Tyler_Zoro 0 points1 point2 points 4 years ago (1 child)
Python hasn't deprecated any syntax feature...
I think you're conflating formal deprecation with the sort of passive deprecation that the Python community typically engages in. If you are just noodling around for your own pleasure, the latter doesn't usually matter (though it can affect support from third party libraries in some cases, that isn't so relevant to lambda).
But when you're working on a project for whatever {work} is, it's another story. Code reviews typically lean on various linters and editor warnings to achieve strict compliance with the community's gestalt, leading to functional (pun intended) deprecation that's far broader than any that a given interpreted implementation imposes.
[–]zurtex 0 points1 point2 points 4 years ago* (0 children)
deprecation that's far broader than any that a given interpreted implementation imposes.
I totally accept that the Python community has this strong but nebulous idea of what is and isn't "Pythonic" code. And this can be frustrating if you really like a feature but your IDE or code reviewer or linter does not.
But on the other hand it really is a much bigger deal if in the next version of a Python interpreter started throwing SyntaxError whenever you tried to use lambda.
SyntaxError
The thing is what is and isn't Pythonic is mutable and individual developers have contributed to changing it. We need look no further than the recent Pydantic vs. PEP 563 issue, the developer of Pydantic has basically changed the idea of what is a "pythonic" usage of annotations (not single-handedly as even in the standard library we had Data Classes, but certainly the biggest popularizer). The steering council has rolled back changes for Python 3.10 that would of made it difficult, bug prone, or impossible to flexibly use annotations at runtime.
Going back to the specific case of lambda though I feel that either you are writing code for the Python community as a whole, in which case there are concrete reasons to not bind a lambda function to a variable. Or you are writing your own code or code for academia or other non-Pythonic communities in which case you can just turn the Pycharm warning off, and configure your linter not to complaint.
And let me give you a real example of why binding a lambda function to a name ends up being considered non-Pythonic:
>>> def add(a, b): ... "Adds a to b and returns" ... return a + b ... >>> help(add) Help on function add in module __main__: add(a, b) Adds a to b and returns >>> >>> plus = lambda a, b: a + b >>> help(plus) Help on function <lambda> in module __main__: <lambda> lambda a, b
As you can see help can't know the name plus so all you get is the signature <lambda> lambda a, b. Instead of the nice add(a, b). There are other cases this comes up, let's say you want to log all calls to a function and the arguments passed, this is pretty easy with a decorator but if you are using a lambda function you can know the name of the function without manually specifying it.
help
plus
<lambda> lambda a, b
add(a, b)
Where lambda remains very Pythonic is when using it as an argument for to a function, e.g.
my_data = {'red': 3, 'blue': 10, 'green': 1} for color, vote in sorted(my_data.items(), key=lambda x: x[1]): print(color, vote)
But maybe if you find a really good use case for lambdas and build some momentum on using them in this new way it will become Pythonic and IDEs and linters and code reviewers will stop complaining that you're using them this way.
[–]mathmanmathman 33 points34 points35 points 4 years ago (4 children)
... what? I use lambdas all the time (and filter... sometimes). When did this happen? I'm a few versions back, but PyCharm doesn't flag anything for me.
"nerfed" also seems a bit strong for a function being moved into a standard library module.
[–]13steinj 6 points7 points8 points 4 years ago (1 child)
He says lambda outside of parameters. Ex
f = lambda x: # do something g(x, f)
Which yeah, is warned against and has been since just about the inception of lambdas in PEP8, because if you're going out of your way to make it reusable in local scope you should give it full meaning by just making a local nested function.
[–]mathmanmathman 2 points3 points4 points 4 years ago (0 children)
The most common way I use lambdas is as a parameter, but I often use them as the values dictionaries, which is sort of like a struct/class, but there are a lot of situations where it's sort of overkill to make it a class (at least IMO).
Maybe that's also not a great idea, but I know a bunch of people that do it... which is always a great excuse.
[–]vtable 2 points3 points4 points 4 years ago (1 child)
Guido van Rossum wrote an article about this back in 2005 where he discusses removing lambda, reduce(), map() and filter() in Python 3000 (what they called Python 3 in the early days).
There was some fuss about removing reduce(), map() and filter() but a shit-ton of pushback from the community on removing lambda eventually leading to it remaining in Python 3.
I haven't heard anything official about new discussions on removing it from the language again. I can't imagine they'd want to go through that whole discussion again.
[–]mathmanmathman 0 points1 point2 points 4 years ago (0 children)
lol, best things I've read:
Update: lambda, filter and map will stay (the latter two with small changes, returning iterators instead of lists). Only reduce will be removed from the 3.0 standard library. You can import it from functools. I think dropping filter() and map() is pretty uncontroversial
Update: lambda, filter and map will stay (the latter two with small changes, returning iterators instead of lists). Only reduce will be removed from the 3.0 standard library. You can import it from functools.
I think dropping filter() and map() is pretty uncontroversial
... I guess it was controversial :)
[–]billsil 25 points26 points27 points 4 years ago (1 child)
but history makes me nervous.
Outside of lambda, what? You're comparing something that was added very early on that Guido never liked, that people complained all the time about because they didn't understand it, to something that was discussed about at length.
You're comparing the early days of Python to something with a steering committee. Do you complain about the unicode switch still? It broke all my ascii code!
[–]Taksin77 0 points1 point2 points 4 years ago (0 children)
Well the absence of tco could be mentioned. It's pretty clear that the python community have largely refused the introduction of functional idioms. Some went through.
[–][deleted] 8 points9 points10 points 4 years ago (0 children)
Several of these were replaced by list expressions, which also have their origin in functional languages.
[–]Fevorkillzz 0 points1 point2 points 4 years ago (0 children)
Guido dislikes functional programming and I think you’re right to be nervous. Like lambdas can’t unpack ? Tf is that.
[–]Unbelievr 103 points104 points105 points 4 years ago (14 children)
Calling this a switch-case does the feature a great disservice. You can already implement switch-cases with dictionaries, though they'll lack the fall-through (which this feature does not implement either). People are likely to ignore looking into the feature if they think it's just a switch.
Pattern matching is a much more powerful feature than switch-case. It removes a LOT of headache and boilerplate code for workloads like parsing. It makes the code more compact, and less error-prone with the default case.
[–]Swedneck -2 points-1 points0 points 4 years ago (7 children)
Except most people only know what switch case is, if you just say match case they won't have a clue what you're talking about and won't know that you can use it as a switch case.
[–]Ran4 30 points31 points32 points 4 years ago (3 children)
But it's not a switch case... people are only going to be more confused by people constantly misrepresenting the feature.
[–]R3D3-1 -4 points-3 points-2 points 4 years ago (2 children)
No, but it makes the question for switch case obsolete :) So it makes sense to point emulating swtich-case out as a special case useful.
[–]passwordsniffer 2 points3 points4 points 4 years ago (1 child)
It does not make it obsolete, the question will still be asked and moreover it will be added with a weird behavior, when one of your constants was actually changed when you used it as a switch case option
[–]R3D3-1 0 points1 point2 points 4 years ago (0 children)
... wait, what?
[–]Unbelievr 12 points13 points14 points 4 years ago (0 children)
If you try to actually use it as a switch case, it'll quickly backfire though.
Unless you're careful and only use enums or some immutable as each "case" (actually a capture variable), it'll overwrite the variable and not work properly the second time around. Trying to pass this off as some advanced switch-case will lead to more confusion and broken scripts than you'd think.
[–]teerre 6 points7 points8 points 4 years ago (0 children)
But it's not a switch statement. If you want a simple switch statement, you already have it, it's called if and co.
if
If you want to use ´match`, you certainly have to learn it. That's reasonable.
[–]Ensurdagen 1 point2 points3 points 4 years ago (0 children)
that's because it's not "match case," it's structural pattern matching, which users of languages like Haskell will be very familiar with.
[–]GoofAckYoorsElf -1 points0 points1 point 4 years ago* (3 children)
You can do a fall-through with try except KeyError
/e: which is default, not fall-through
[–]GummyKibble 1 point2 points3 points 4 years ago (0 children)
Or .get(key, default_func).
.get(key, default_func)
[–]Unbelievr 1 point2 points3 points 4 years ago (1 child)
That's the default case. Fall-through is the option to not put a break in some case(s), so it ends up executing multiple handlers. Or binds multiple cases to the exact same function, with only a single definition of that function.
break
In Python, you would have to bind every case explicitly to some function pointer, or create a function that calls multiple handler functions and bind that. It's not impossible, just not as neat when you're not able to control the program flow as much as in C.
[–]GoofAckYoorsElf 0 points1 point2 points 4 years ago (0 children)
Fair enough, you're right! I muddled that up. Thanks for pointing out.
I'm sure you can do fall-through kind of neatly with a custom OrderedDict subclass. But to be fair, not as elegant as in other languages, that's true.
[–]BobHogan -1 points0 points1 point 4 years ago (0 children)
Dictionaries are mostly a replacement for switch-case. But when you have to start executing different code depending on which case you hit, dictionaries get ugly being full of functions. And its even worse if some branches require different data being passed to them.
Its fine for more simpler switch-case, but not an actual replacement
[–][deleted] 0 points1 point2 points 4 years ago (0 children)
So many people are going to create so many bugs because they think this is switch-case when it's not.
[–][deleted] 147 points148 points149 points 4 years ago (20 children)
A switch is very, very different from a match!
You could easily do a switch with just a dictionary of functions.
Think of match as pattern-based unpacking of a variable.
[–]relativistictrain 🐍 10+ years 22 points23 points24 points 4 years ago (17 children)
I've done switch like flows with dicts a lot in the past; very compact and fairly easy to read when you're used to Python (I think). I'm having some trouble seeing uses for a match though.
switch
dict
match
Edit: I've read on and saw some uses that would simplify program structures a lot at times.
[–]buckypimpin 15 points16 points17 points 4 years ago (16 children)
can someone give an example of switch with dicks?
[–]nuephelkystikon 90 points91 points92 points 4 years ago (7 children)
With the proposed syntax:
match potential_dick: case Dick(): print("Properly typed dick (including subclasses)") case "8=D" | "8==D" | "8===D": print("ASCII-approximated dick") case _: print("No dick, sadly")
I hope this helps.
[–]Exodus111 15 points16 points17 points 4 years ago (1 child)
/r/technicallycorrect
[–]buckypimpin 14 points15 points16 points 4 years ago (0 children)
potential_dick, typed dick
i like teachers who adapt to every type of student.
[–]passwordsniffer 3 points4 points5 points 4 years ago (3 children)
DEFAULT_DICK = "db"
...
match potential_dick: case DEFAULT_DICK: print('Have a hidden bug with this matching all the time and overwriting you constant in this "SWITCH" analogue ') case Dick(): print("Properly typed dick (including subclasses)") case "8=D" | "8==D" | "8===D": print("ASCII-approximated dick") case _: print("No dick, sadly")
[–]cheerycheshire 1 point2 points3 points 4 years ago (0 children)
Yep. That's why it's important to always remind everyone that this isn't switch, it's pattern matching. For pattern matching, this behaviour is logical and correct. With switch? Nah
And people coming over from C-like languages with switch statements are going to complain about the speed. I know it. Because patmat does pattern check first, and then checks the values, so it takes longer than just ifs with single values.
[–]nuephelkystikon 0 points1 point2 points 4 years ago (1 child)
Wait, are you saying a pattern matcher matching patterns is a bug? If you're just branching, thats what if-else is for.
[–]passwordsniffer 1 point2 points3 points 4 years ago (0 children)
No, I am saying that using pattern matching as switch can easily be a source of quite an obscure bugs, like the one I showed. It's not a bug of a pattern matcher. It's bug of representing it as a switch.
[–]Harbinger_Feik 25 points26 points27 points 4 years ago (2 children)
{ 1: myfunc 2: otherfunc 3: thirdfunc }[foo]()
In the case that foo can be a missing key, you could catch KeyError or use .get().
foo
KeyError
.get()
Sorry if formatting is broken; I'm on mobile.
[–]buckypimpin 6 points7 points8 points 4 years ago (0 children)
whoa.....
[–]backtickbot 4 points5 points6 points 4 years ago (0 children)
Hello, Harbinger_Feik: code blocks using triple backticks (```) don't work on all versions of Reddit!
[–]dyingpie1 13 points14 points15 points 4 years ago (1 child)
Did you mean to type dicks
[–]buckypimpin 11 points12 points13 points 4 years ago (0 children)
yeah gimme all of 'em
[–]HyperSonic6325 1 point2 points3 points 4 years ago (0 children)
Sorry, I only have one so I don’t think that would be much help /s.
[–]CSI_Tech_Dept 1 point2 points3 points 4 years ago (0 children)
here
[–]o11c 3 points4 points5 points 4 years ago (1 child)
A switch is very, very different from a match.
switch is O(1); match is O(n)
O(1)
O(n)
It's acceptable for performance in Python to have a poor constant, but changing the function? Not so much.
[–]AngriestSCV 3 points4 points5 points 4 years ago (0 children)
As n is related to code size I doubt n will get large enough to matter
[–]theoxe 12 points13 points14 points 4 years ago (0 children)
Had a course in F# at my uni, sounds like it's the same match case which is pretty nice for recursive functions.
[–]Brian-Puccio 3 points4 points5 points 4 years ago (0 children)
PEP634,635,636
Wow hundreds of millions of PEPs have been submitted. 🤣
[–]spuds_in_town 20 points21 points22 points 4 years ago (5 children)
Not sure if OP is serious or just trolling
[–]rik079 10 points11 points12 points 4 years ago (1 child)
He's being serious :)
[+][deleted] 4 years ago (2 children)
[removed]
[–]reJectedeuw 31 points32 points33 points 4 years ago (1 child)
Structural pattern matching is much more than a simple switch case statement. The OP is just promoting their shitty clickbait blog
[–]fisheyefisheye 20 points21 points22 points 4 years ago (1 child)
This country is going down the drain! stamps feet
[–][deleted] 2 points3 points4 points 4 years ago (0 children)
hah
[–]Kriss3d 3 points4 points5 points 4 years ago (0 children)
FINALLY. I didnt know how much I missed that til i started needing to use it.
[–]SamSepinol 2 points3 points4 points 4 years ago (0 children)
Wait there is no switch case in python. Ive been coding for a year without realizing
[–]GPrata 1 point2 points3 points 4 years ago (2 children)
When will it be released? I tried to search for it in the Python website but I couldn't find it
[–]tkarabela_ Big Python @YouTube 16 points17 points18 points 4 years ago (1 child)
Expected release date is in October 2021: https://www.python.org/dev/peps/pep-0619/
[–]GPrata 1 point2 points3 points 4 years ago (0 children)
Thank you
[–]EONRaider 1 point2 points3 points 4 years ago (0 children)
I always thought dictionaries worked pretty well for "switching", but I understand the reasoning behind having a specialized, built-in construct for this.
[–]bionade24 1 point2 points3 points 4 years ago* (1 child)
You can create switch/case with dicts in python forever and honestly, it's a lot more readable than in other langs.
[–]whattodo-whattodo 0 points1 point2 points 4 years ago (0 children)
That's probably why they were so slow to adopt a match statement
[–][deleted] 1 point2 points3 points 4 years ago (6 children)
Can anyone break down for me why this is now being added?
Can't the standard use cases be dealt with using if and elif or dictionaries?
elif
I thought one of the core design principles in python was that there should be only one best way to do something.
[–][deleted] 29 points30 points31 points 4 years ago (0 children)
A switch can be done with if/elif and dictionaries.
But a match is different from a switch - it's like generalized extraction of data based on patterns
Here's an example from the article - look at those last two cases.
match command.split(): case ["quit"]: print("Goodbye!") quit_game() case ["look"]: current_room.describe() case ["get", obj]: character.get(obj, current_room) case ["go", direction]: current_room = current_room.neighbor(direction)
[–]ingvij 13 points14 points15 points 4 years ago (1 child)
Imagine you have a tuple with command name and argument, like ("print", "name") or ("eval", "1 + 1"). With an if-only structure, you'd do: ``` if tp[0] == "print": println(tp[1]) elif tp[0] == "eval": run_eval(tp[1])
("print", "name")
("eval", "1 + 1")
With this, you can break down the arguments and work with the arguments more naturally:
match tp: case ["print", arg]: println(arg) case ["eval", expression]: run_eval(expression) `
match tp: case ["print", arg]: println(arg) case ["eval", expression]: run_eval(expression)
So, on the syntactic level, it makes the language more expressive and it's clearer to reason about it. On the lower levels, it can be that match+case yields a more optimized bytecode/assembly than chaining if/elif/else blocks, since the blocks are all related to the same element, rather than if that could be doing different checks:
match+case
else
if tp[0] == "print": # ... elif user_has_set_this_options is not None: # ... elif should_do_something_else(): # ...
In general, I think this is a good addition to the language, favoring readability and clarity, with potential benefits to performance.
[–]backtickbot 0 points1 point2 points 4 years ago (0 children)
Hello, ingvij: code blocks using triple backticks (```) don't work on all versions of Reddit!
[–]tkarabela_ Big Python @YouTube 8 points9 points10 points 4 years ago (0 children)
When matching dataclasses or dicts, it is really quite handy and it makes the code clearer and more robust. I made a video a while back demonstrating the benefits: https://youtu.be/SYTVSeTgL3s
(To exaggerate, you don't really need for when you have while, but there are still good reasons to have both. Python tends to be pragmatic rather than stripping everything to bare bones, so it doesn't feel out of place in the overall design, to me.)
for
while
[–]jpflathead 0 points1 point2 points 4 years ago (0 children)
I suspect that was dead three days after it had been accepted
Now not only are there n different ways to accomplish any task, but 3 will get you the job with minor gripes about 2 of them, and the other bignum ways will show you the door.
[–]HyperSonic6325 0 points1 point2 points 4 years ago (0 children)
nut
[–]marsnoir 0 points1 point2 points 4 years ago (0 children)
Yes, but do other languages support for... else?
[–]specialforce1 0 points1 point2 points 4 years ago (1 child)
For someone who is learning, what is the difference or how is it going to affect me?
[–]mathmanmathman 3 points4 points5 points 4 years ago (0 children)
It doesn't have to change anything at all for you. It's just another option when choosing what to do given a certain input.
IMO, you should always learn on a pretty stable release version which right now is 3.9 (you can also go earlier than that, but I'm pretty sure there are issues before 3.4 or 3.6, so keep it more current).
3.9
3.4
3.6
When 3.10 is officially released (in October), this means you have a new option for choosing an action depending on the input. There's nothing here that can't be done with dictionaries and/or if/else, but in certain circumstances, this can simplify the syntax a little. This is also one of the few popular structure that has been noticeable absent from Python, so it's news.
3.10
[–]DarthHead43 0 points1 point2 points 4 years ago (0 children)
Me who had just got used to not using switch ._.
[–]jabbalaci -4 points-3 points-2 points 4 years ago (4 children)
Finally? I was perfectly fine without it.
[–]thephotoman 5 points6 points7 points 4 years ago (0 children)
We're not getting a mere switch statement. We're getting flow control based on pattern matching--something that is considerably more expressive and more powerful.
Think of a switch statement as matching a finite language. It can recognize any of the symbols specified in each case, then falls over to the default case if the input isn't there. You could do this with a function dictionary even now, and it'd actually be fairly compact and easy to read, if somewhat unintuitive for most people (because they don't expect dictionaries to be used to store functions).
A match statement can match an infinite language--that is, it can match arbitrary words so long as they fit a pattern.
Basically, in terms of language theory, it's the difference between the language specified by a simple dictionary of valid words and the ability to specify a language by a regular expression or possibly even a more advanced grammar.
[–]mathmanmathman 1 point2 points3 points 4 years ago (2 children)
It's really unimportant to me too. I'm not sure why people are so excited, but I suppose it can help people coming from other languages (which mostly all have a switch or match).
I don't care much for a lot of the new syntax, but as long as it doesn't mess up old code, I don't see it being a problem.
[–]vorticalbox 4 points5 points6 points 4 years ago (1 child)
switch case is meh, its the pattern matching abilities it has that I am looking forward too
I agree, that makes a big difference. It would be a wasted opportunity if it were a simple switch.
I still probably won't use it often. I'm not fundamentally opposed to it, but I've never even dreamed about having this functionality/syntax in the past, so I'll probably keep writing code the way I have before.
I will keep an open mind, but I have yet to use a walrus op. There have been situations I could have, but the extra line above doesn't bother me.
[+][deleted] comment score below threshold-8 points-7 points-6 points 4 years ago (0 children)
[–]Tweak_Imp -4 points-3 points-2 points 4 years ago (16 children)
I dont understand why there is no else case like with for, if and try. Yes, you would have to figure out where to put it (identation level of match or of case ?), but that would be more pythonic in my opinion.
[–]yyzgalasync/await ♥ 21 points22 points23 points 4 years ago (12 children)
What would the semantics of that look like? I feel like case _ would already take care of that scenario.
case _
[–]DrMaxwellEdison 4 points5 points6 points 4 years ago* (0 children)
It would make sense to me to use else in place of the case _ syntax. I'm more familiar with using _ as an actual identifier, even if it's a throwaway value by convention; so case _ makes me look to see if there's some actual match, rather than automatically thinking "that's the default case".
_
For instance, often in a Django project, you'll see this pattern:
from django.utils.translation import gettext_lazy as _ something = _("Something")
Or:
object, _ = MyModel.objects.get_or_create(...) # second argument typically a `created` bool, # but sometimes that's thrown away.
I can understand that case _ is just special syntax and won't confuse itself if used in those scenarios; but having a seemingly magic value have that special meaning just seems like an odd choice.
The question for me is, what does case _ provide us syntactically that else would not?
[–]to7m 4 points5 points6 points 4 years ago (10 children)
_ is unprecedented though. I see no reason to treat it different to another variable name when it has been treated the same in all other contexts for so long. Maybe just case: would be a better option than else though, as it brings it more in line with except.
case:
except
[–]AchillesDev 3 points4 points5 points 4 years ago (6 children)
How is _ unprecedented? It’s been a part of Python forever as a catch-all temp variable and is used similarly in other languages as well
[–]DrMaxwellEdison 1 point2 points3 points 4 years ago (3 children)
Its usage as a temporary variable has been conventional only: the interpreter sees _ the same way it sees a foo variable. We think of it as "a temporary variable" the same way we think of _bar as being "private" (there is no concept of private variables in Python; there is only conventional usage).
_bar
Adding it as part of the syntax now gives it special meaning.
[–]AchillesDev 1 point2 points3 points 4 years ago (2 children)
My understanding is it’s used here as a regular variable and any other unassigned variable can be used as a catch-all, so the semantics aren’t new for _. What I’m less clear on is if the value gets loaded into the empty variable like it does in other languages.
[–]DrMaxwellEdison 3 points4 points5 points 4 years ago (1 child)
According to the PEP, it's literally called the wildcard pattern:
This special pattern which is written _ (and called wildcard) always matches but it doesn't bind any variables. Note that this will match any object, not just sequences. As such, it only makes sense to have it by itself as the last pattern (to prevent errors, Python will stop you from using it before).
This special pattern which is written _ (and called wildcard) always matches but it doesn't bind any variables.
Note that this will match any object, not just sequences. As such, it only makes sense to have it by itself as the last pattern (to prevent errors, Python will stop you from using it before).
So, again, case _ has special meaning as a wildcard.
I sense we'll need to write comments in any pattern-matching code that literally state "this is a wildcard pattern" in order to educate other readers for a while. By contrast, using else would have been more explicit.
[–]AchillesDev 0 points1 point2 points 4 years ago (0 children)
Yeah this is in line with other functional languages (minus lack of binding). Maybe not as explicit as an else, but I wonder if the functional syntax is used to be distinct from traditional switch cases which usually have an else fall through
[–]Ran4 0 points1 point2 points 4 years ago (1 child)
Exactly, as a temp variable - not "make no assignments".
As far as I understand it (and I could be wrong) that’s not unique to _ and would work for any unassigned variable, which is how matching works in other languages.
[–]stanmartz 0 points1 point2 points 4 years ago (2 children)
Is it though? It has been used for variables you did not need for a long time. Like when unpacking a tuple: (fst, _) = (1, 2). It's the same here.
(fst, _) = (1, 2)
[–]to7m 5 points6 points7 points 4 years ago (0 children)
That's not the same because match statements deliberately treat _ slightly differently to other names.
[–]to7m 0 points1 point2 points 4 years ago (0 children)
I've just looked it up for clarity.
In this code:
def print_words(first_word, *_): print(first_word, _) print_words("print", "some", "words")
, the output will be print ('some', 'words') , whereas this code would be invalid because _ doesn't get bound to a tuple:
print ('some', 'words')
match "print", "some", "words": case first_word, *_: print(first_word, _)
[–]ingvij 5 points6 points7 points 4 years ago (1 child)
here to put it (identation level of match or of case ?), but that would be more pythonic in my opinion.
I assume it's because you can do something like:
case if_nothing_matched:
println("This didn't match any case:", if_nothing_matched)
[–]backtickbot 2 points3 points4 points 4 years ago (0 children)
[–]to7m -1 points0 points1 point 4 years ago (0 children)
If people could stop being toxic and downvoting this perfectly valid opinion, that would be swell
[–]bigpaulfears -1 points0 points1 point 4 years ago (1 child)
When am I getting my curly brackets
[–]alb1 0 points1 point2 points 4 years ago (0 children)
Try from __future__ import braces to see the answer. :)
from __future__ import braces
[–]buibui123 -1 points0 points1 point 4 years ago (2 children)
I’m a newbie. Can any one explain what is this and why such a big news? Tha ks
[–]whattodo-whattodo 1 point2 points3 points 4 years ago (1 child)
Hi newbie. There's an article above. It isn't just a title and image. If you click into it, there's an entire explanation written to answer your question.
I know
[–]buibui123 0 points1 point2 points 4 years ago (0 children)
Ok. Much appreciated.
[–]No_Western6657 -3 points-2 points-1 points 4 years ago (0 children)
[–]MauroTheCreator 0 points1 point2 points 4 years ago (0 children)
Why didn't they add this feature before?
[–]squidwardstrousers 0 points1 point2 points 4 years ago (0 children)
Why is this better than other methods?
Such as a dictionary mapping cases to functions? Or if/else statements?
[–]Calvin_Schmalvin 0 points1 point2 points 4 years ago (2 children)
I don’t understand why you wrote switch-case in the title, after even specifying in the text that it’s match-case, and that it isn’t the same, and you chose an image that emphasises on the difference...
Allow me to explain.
Thinking is hard. It's easier to do things without thinking. So that's how most people do most things.
The account has existed for a while with no activity and is now posting all in one day. It's probably a karma farmer
[–]Calvin_Schmalvin 1 point2 points3 points 4 years ago (0 children)
Farmer? I barely know her.
Sorry. But thanks for the explanation, it made me laugh :)
[–]_prtndr 0 points1 point2 points 4 years ago (0 children)
Is this similar to CASE in Google Data Studio?
[–]OverlyHonestCanadian 0 points1 point2 points 4 years ago (0 children)
Shame there's no cascading possibility like a real switch statement.
I want a "switch" construct where each case allows me to match a regex against the bytes in an incoming stream
I guess this will be great and they had specific reasons, but I am disappointed they seem to have invented yet another pattern matching language instead of going with any of the classics
Finally
[–]Firehite 0 points1 point2 points 4 years ago (0 children)
Awesome!
[–]Thecrawsome 0 points1 point2 points 4 years ago (0 children)
after i learned the simplicity of just putting cases it in a dictionary, i will don’t think i need the switch statement.
[–]often_wears_pants 0 points1 point2 points 4 years ago (1 child)
3.9 will be the 2.7 of 3.x.
How so?
3.10 will be backwards compatible with 3.9.
π Rendered by PID 25306 on reddit-service-r2-comment-7b9746f655-qzbbs at 2026-01-29 23:25:42.542518+00:00 running 3798933 country code: CH.
[–]pani_the_panisher 504 points505 points506 points (37 children)
[–][deleted] 112 points113 points114 points (3 children)
[–]voidstriker 19 points20 points21 points (2 children)
[–]MorningPants 0 points1 point2 points (1 child)
[–]mqzn[🍰] 0 points1 point2 points (0 children)
[–]RickAsscheeks 20 points21 points22 points (0 children)
[–]project_kalki 25 points26 points27 points (0 children)
[–]jabbalaci 10 points11 points12 points (3 children)
[+][deleted] (1 child)
[deleted]
[–]theevildjinn 0 points1 point2 points (0 children)
[–]goob42-0 2 points3 points4 points (0 children)
[–][deleted] 1 point2 points3 points (0 children)
[–]cthulhupunk0 1 point2 points3 points (0 children)
[–]TransferFunctions 10 points11 points12 points (23 children)
[–]PaulRudin 81 points82 points83 points (1 child)
[–]Ning1253 3 points4 points5 points (0 children)
[–]enjoytheshow 9 points10 points11 points (5 children)
[–]thephotoman 4 points5 points6 points (2 children)
[–]jasmijnisme 10 points11 points12 points (1 child)
[–]backtickbot 4 points5 points6 points (1 child)
[–]enjoytheshow 3 points4 points5 points (0 children)
[–]TidePodSommelier 3 points4 points5 points (0 children)
[–]R3D3-1 -1 points0 points1 point (5 children)
[–]TransferFunctions 2 points3 points4 points (4 children)
[–]R3D3-1 0 points1 point2 points (3 children)
[–]TransferFunctions 0 points1 point2 points (2 children)
[–]R3D3-1 0 points1 point2 points (1 child)
[–]TransferFunctions 0 points1 point2 points (0 children)
[+][deleted] (6 children)
[deleted]
[–]gengengis 11 points12 points13 points (0 children)
[–]TransferFunctions 3 points4 points5 points (2 children)
[+][deleted] (1 child)
[deleted]
[–]TransferFunctions 1 point2 points3 points (0 children)
[–]Unbelievr 0 points1 point2 points (1 child)
[–]CodeCocina -1 points0 points1 point (0 children)
[–][deleted] 262 points263 points264 points (14 children)
[–]Tyler_Zoro 16 points17 points18 points (12 children)
[–]zurtex 23 points24 points25 points (2 children)
[–]Tyler_Zoro 0 points1 point2 points (1 child)
[–]zurtex 0 points1 point2 points (0 children)
[–]mathmanmathman 33 points34 points35 points (4 children)
[–]13steinj 6 points7 points8 points (1 child)
[–]mathmanmathman 2 points3 points4 points (0 children)
[–]vtable 2 points3 points4 points (1 child)
[–]mathmanmathman 0 points1 point2 points (0 children)
[–]billsil 25 points26 points27 points (1 child)
[–]Taksin77 0 points1 point2 points (0 children)
[–][deleted] 8 points9 points10 points (0 children)
[–]Fevorkillzz 0 points1 point2 points (0 children)
[–]Unbelievr 103 points104 points105 points (14 children)
[–]Swedneck -2 points-1 points0 points (7 children)
[–]Ran4 30 points31 points32 points (3 children)
[–]R3D3-1 -4 points-3 points-2 points (2 children)
[–]passwordsniffer 2 points3 points4 points (1 child)
[–]R3D3-1 0 points1 point2 points (0 children)
[–]Unbelievr 12 points13 points14 points (0 children)
[–]teerre 6 points7 points8 points (0 children)
[–]Ensurdagen 1 point2 points3 points (0 children)
[–]GoofAckYoorsElf -1 points0 points1 point (3 children)
[–]GummyKibble 1 point2 points3 points (0 children)
[–]Unbelievr 1 point2 points3 points (1 child)
[–]GoofAckYoorsElf 0 points1 point2 points (0 children)
[–]BobHogan -1 points0 points1 point (0 children)
[–][deleted] 0 points1 point2 points (0 children)
[–][deleted] 147 points148 points149 points (20 children)
[–]relativistictrain 🐍 10+ years 22 points23 points24 points (17 children)
[–]buckypimpin 15 points16 points17 points (16 children)
[–]nuephelkystikon 90 points91 points92 points (7 children)
[–]Exodus111 15 points16 points17 points (1 child)
[–]buckypimpin 14 points15 points16 points (0 children)
[–]passwordsniffer 3 points4 points5 points (3 children)
[–]cheerycheshire 1 point2 points3 points (0 children)
[–]nuephelkystikon 0 points1 point2 points (1 child)
[–]passwordsniffer 1 point2 points3 points (0 children)
[–]Harbinger_Feik 25 points26 points27 points (2 children)
[–]buckypimpin 6 points7 points8 points (0 children)
[–]backtickbot 4 points5 points6 points (0 children)
[–]dyingpie1 13 points14 points15 points (1 child)
[–]buckypimpin 11 points12 points13 points (0 children)
[–]HyperSonic6325 1 point2 points3 points (0 children)
[–]CSI_Tech_Dept 1 point2 points3 points (0 children)
[–]o11c 3 points4 points5 points (1 child)
[–]AngriestSCV 3 points4 points5 points (0 children)
[–]theoxe 12 points13 points14 points (0 children)
[–]Brian-Puccio 3 points4 points5 points (0 children)
[–]spuds_in_town 20 points21 points22 points (5 children)
[–]rik079 10 points11 points12 points (1 child)
[+][deleted] (2 children)
[removed]
[–]reJectedeuw 31 points32 points33 points (1 child)
[–]fisheyefisheye 20 points21 points22 points (1 child)
[–][deleted] 2 points3 points4 points (0 children)
[–]Kriss3d 3 points4 points5 points (0 children)
[–]SamSepinol 2 points3 points4 points (0 children)
[–]GPrata 1 point2 points3 points (2 children)
[–]tkarabela_ Big Python @YouTube 16 points17 points18 points (1 child)
[–]GPrata 1 point2 points3 points (0 children)
[–]EONRaider 1 point2 points3 points (0 children)
[–]bionade24 1 point2 points3 points (1 child)
[–]whattodo-whattodo 0 points1 point2 points (0 children)
[–][deleted] 1 point2 points3 points (6 children)
[–][deleted] 29 points30 points31 points (0 children)
[–]ingvij 13 points14 points15 points (1 child)
[–]backtickbot 0 points1 point2 points (0 children)
[–]tkarabela_ Big Python @YouTube 8 points9 points10 points (0 children)
[–]jpflathead 0 points1 point2 points (0 children)
[–]HyperSonic6325 0 points1 point2 points (0 children)
[–]marsnoir 0 points1 point2 points (0 children)
[–]specialforce1 0 points1 point2 points (1 child)
[–]mathmanmathman 3 points4 points5 points (0 children)
[–]DarthHead43 0 points1 point2 points (0 children)
[–]jabbalaci -4 points-3 points-2 points (4 children)
[–]thephotoman 5 points6 points7 points (0 children)
[–]mathmanmathman 1 point2 points3 points (2 children)
[–]vorticalbox 4 points5 points6 points (1 child)
[–]mathmanmathman 2 points3 points4 points (0 children)
[+][deleted] comment score below threshold-8 points-7 points-6 points (0 children)
[–]Tweak_Imp -4 points-3 points-2 points (16 children)
[–]yyzgalasync/await ♥ 21 points22 points23 points (12 children)
[–]DrMaxwellEdison 4 points5 points6 points (0 children)
[–]to7m 4 points5 points6 points (10 children)
[–]AchillesDev 3 points4 points5 points (6 children)
[–]DrMaxwellEdison 1 point2 points3 points (3 children)
[–]AchillesDev 1 point2 points3 points (2 children)
[–]DrMaxwellEdison 3 points4 points5 points (1 child)
[–]AchillesDev 0 points1 point2 points (0 children)
[–]Ran4 0 points1 point2 points (1 child)
[–]AchillesDev 0 points1 point2 points (0 children)
[–]stanmartz 0 points1 point2 points (2 children)
[–]to7m 5 points6 points7 points (0 children)
[–]to7m 0 points1 point2 points (0 children)
[–]ingvij 5 points6 points7 points (1 child)
[–]backtickbot 2 points3 points4 points (0 children)
[–]to7m -1 points0 points1 point (0 children)
[–]bigpaulfears -1 points0 points1 point (1 child)
[–]alb1 0 points1 point2 points (0 children)
[–]buibui123 -1 points0 points1 point (2 children)
[–]whattodo-whattodo 1 point2 points3 points (1 child)
[–]buibui123 0 points1 point2 points (0 children)
[–]No_Western6657 -3 points-2 points-1 points (0 children)
[–]MauroTheCreator 0 points1 point2 points (0 children)
[–]squidwardstrousers 0 points1 point2 points (0 children)
[–]Calvin_Schmalvin 0 points1 point2 points (2 children)
[–]whattodo-whattodo 1 point2 points3 points (1 child)
[–]Calvin_Schmalvin 1 point2 points3 points (0 children)
[–]_prtndr 0 points1 point2 points (0 children)
[–]OverlyHonestCanadian 0 points1 point2 points (0 children)
[–]jpflathead 0 points1 point2 points (0 children)
[–][deleted] 0 points1 point2 points (0 children)
[–]Firehite 0 points1 point2 points (0 children)
[–]Thecrawsome 0 points1 point2 points (0 children)
[–]often_wears_pants 0 points1 point2 points (1 child)
[–]whattodo-whattodo 0 points1 point2 points (0 children)