13 ms·
What Is the Switch-Case Equivalent in Python?
- dmarchand90 6y agoI'm really worried for the long term health of python. The philosophy of python is there should be only one pythonic way of doing things. But more and more features are being added that give too many options with minor benefit How is case different from the elif pattern? What does the walrus operator do that we really need. Each one of these things on their own if fine but I'm worried together it's going to make python increasingly idiosyncratic to each developer and, consequently, harder to read. Python's Zen beat out perl's TMTOWTDI. But python seems to try to be more and more like perl with every release: more appealing to hackers playing code golf than long term readers of the code base
- neolog 6y agoThe walrus operator was definitely a mistake. But type annotations, pattern matching, attrs/dataclasses, and f-strings are significant improvements.
- jsmeaton 6y agoSee though, this is the issue. What you see as a useful or mistaken feature is likely a different set to another user, just as we’ve seen above. I think it’s a mistake to defer to the zen of python without considering the PEPs themselves which do discuss trade offs. (I’ll note that you didn’t make that claim but GP did).
- neolog 6y agoTbh I think a consensus of expert Pythonistas would agree with me. Walrus only got through because of the "dictatorship".
- jsmeaton 6y agoPerhaps :) That’s not a hill I’m willing to die on but I agree with the positives from your list. And the small handful of times I’ve used walrus have been nice, but not game changing.
- musingsole 6y agoLanguage features of this type should be nice and not game changing. It's how spoken word languages evolve. If every change was game-changing, it'd only be a few mutations until a dialect became a language in its own right. In reality, you get countless dialects frequently with features that eventually die off and new languages rarely and only in the aggregate.
- GeorgeTirebiter 6y agoSeems to me the 'sweet spot' for a language is a careful balance of continuing to evolve - slowly, carefully - and to not become so large as to 'not fit into one head'. Python3.9 is not yet at the 'too big for one head'; but 3.xx could be. Perhaps old-style features need to be removed, and only available via some sort of "from __past__ import old-feature-set"
- neolog 6y agoThey could just deprecate without removing.
- musingsole 6y agoIt's hard for me to separate a language from what it is used to accomplish, and from that perspective, Python has been far too large to fit in one head for a good long time. Perhaps that is why I don't find any compulsion for language purity.
- neolog 6y ago> too large to fit in one head is it? I don't think the core language is that big. The libraries are big of course.
- bobbylarrybobby 6y agoCan you explain why you don’t like the walrus operator? I personally love it.
- neolog 6y ago- Languages should only make special syntax for very common or very important needs. Neither applies here. - It violates the longstanding Python rule that assignments don't escape the enclosing scope.
- smetj 6y ago> It violates the longstanding Python rule that assignments don't escape the enclosing scope. But doesn't that violate the longstanding Python rule that A Foolish Consistency is the Hobgoblin of Little Minds ?
- neolog 6y agoNo. Assignment leaking into enclosing scope is a bad idea.
- beforeolives 6y agoThe trick is tell when striving for consistensy is foolish and when it isn't. Otherwise you would always be able to fall back on this quote to justify creating unuseable code/frameworks/projects/languages.
- bobbylarrybobby 6y agoDon’t assignments already escape scope? if True: x = 1 print(x)
- neolog 6y ago`if` blocks don't make a scope. Comprehensions do.
- mixmastamyk 6y ago
- coldtea 6y ago>The walrus operator was definitely a mistake. Was it tho? It's one of my favorite improvements, and has no actual downside.
- andi999 6y agoSo what is the current one and only one pythonic way when you need a switch statement (like having a lot of cases to handle). I see two possibilities: 1.a lot of 'if'-statement 2.using a dict and the value is a function you call if the key matches Or what else?
- extradesgo 6y agoI have used this dict solution before in scripts and I am not proud of it.
- staticautomatic 6y agoWhy not? What’s wrong with this pattern?
- diarrhea 6y agoNot the parent commenter, but I use that pattern all the time, mainly to match CLI flags/args/options to an action. Say you have a program like "docker-compose". It has multiple subcommands. Each subcommand is a dict string key and the appropriate action to take is its value, a callable. This also plays well with argparse's parser "choices" argument. The by far biggest downside is then that all callables mustn't take arguments, or take all the same ones. You cannot dispatch to a callable and dynamically assign what arguments to call it with without losing the prior benefits. Then it gets awkward (like having to throw around args and kwargs all over the place). But up to that point, I find the pattern useful in this case.
- klyrs 6y agoThere's one that's even closer to c-like switches: a list/tuple of functions or values, indexed by a small int. If you're feeling extremely cheeky, it can even handle negative cases. You'll have to implement fallthrough yourself, though.
- rualca 6y ago> There's one that's even closer to c-like switches: a list/tuple of functions or values, indexed by a small int. That sounds like a desperate plea to get stuck with a bug-riddled unmaintainable mess of a module. If all you want to do is pick one of a finite set of possible code paths, it is never a good idea to generate a hash to pick from a map/array. Even chained if/else if statements are cleaner than that mess.
- G3rn0ti 6y agoYeah, Perl’s been there a long time ago. Initially, Perl did not have a native switch/case statement. However, early on Perlers started to obsess about emulated switch constructs and so Perl 5.10 shipped given/when which was supposed to become the language‘s official switch implementation. But it never really quite took of. While part of it was due to a subtle bug I‘d argue nobody actually needed it. 99% of the time if/elsif/else is good enough and otherwise you might want to consider a dispatch table if the number of cases is large. Beyond Perl this is true in most languages: If you find yourself in a situation to need an extensive if/else chain and to wish for C-like switch/case you’re either writing a parser or you should really rethink about your software‘s architecture (maybe in terms of OOP).
- at_a_remove 6y agoRight there with you! I get it, languages have to grow or fix mistakes. I read about Python long before I attempted to program in it and even I (not a language designer or that special) knew that their handling of division as being integer division as a default was a long-term problem that would eventually be changed one way or another. And so it was. I absolutely agree on the walrus operator. It's too terse and while on its own it only makes two steps into one, it's not used alone, making each line of code with it that much harder to unpack. I don't know enough about pattern matching but my feeling is that we got along without it so far ...
- aduitsis 6y agoNow people are getting worried Python may become like Perl :). With all due respect to your (otherwise perfectly valid) argument, "there's more than one way to do it" was never a real problem with people using Perl. I dare say it's fully possible to write difficult-to-read code in any language. Perl was expressly never interested in erecting glass walls and force people this or that way. Not saying that this is good or bad. But it's the way the people who are making Perl want it.
- vram22 6y agoI had said this some weeks ago, in reply to a tweet by Guido: https://mobile.twitter.com/vasudevram/status/1327364281797525510 https://mobile.twitter.com/vasudevram/status/132736428179752...
- DangitBobby 6y agoMy perspective on this is totally different. I don't like python because I find it to be a simple language. I like python because it's powerful, expressive, flexible, and gets out of my way while I express my intent. I quite like rust as well (for different reasons), and after using pattern matching in it, I am so excited to see it in Python. I can't think of a single change to the language that has been made that I would consider questionable, but I keep hearing complaints about them. Nothing specific to the features themselves though, the complaints are less targeted about how specifically this feature does not belong in the language as a whole, but just general noises about how peoole are worried about changes. It's quite tiresome, I must say, to have it come up in literally every discussion of Python on this forum.
- sullyj3 6y ago> How is case different from the elif pattern? Pattern matching is often conflated with switch-case by people who are unfamiliar, because pattern matching subsumes switch-case, but they're very much not the same thing. Structural pattern matching is much more powerful than checking a series of boolean conditions. It allows you to not only check the structure of a value, but bind parts of that structure to variables. It allows you to express logic that would would otherwise be fairly complex in a straightforward and transparent way.
- earthboundkid 6y ago> If the implementation is hard to explain, it's a bad idea. > If the implementation is easy to explain, it may be a good idea. Pattern matching is extremely complex, and for what?
- jsmeaton 6y agoAppealing to nothing but the zen of python is not an acceptable argument. Pattern matching is not (necessarily) extremely complex as it exists in a multitude of languages these days. Powerful does not automatically imply complex.
- earthboundkid 6y agoAcceptable to whom? Anyhow, read the PEP. It is an extremely complex new language feature.
- jsmeaton 6y agoTo many in the core team, for one. It’s a cutesy easter egg at best not a mission statement. I’ve read the pep. The nature of peps are complete by design. The concept is not overly complex especially since it exists in a number of other languages.
- otabdeveloper4 6y agoPython already has (limited) pattern matching. Example: for foo, (bar, baz) in nested_tuple_list: ... This works as expected. The current 3.10 implementation is just half-baked. They should have expanded the existing pattern matching facilities (added support for data structure destructuring). Presumably then you could just have used the existing walrus operator inside the already existing if-else constructs. That would have been the obvious path of least surprise. What we got instead seems inadequate.
- cbryan 6y ago> The philosophy of python is there should be only one pythonic way of doing things. Thiiis really hasn't been my experience with the Python community. Every place I've worked on a Python codebase has done it a different way, and none of them have agreed on what is "pythonic". Each team has claimed that _their_ approach is the most python-y way to do it, but they've all celebrated Python as not being "restrictive" like "other" languages. It's really weird.
- antpls 6y agoTrue, because that was already a hard problem by itself. And it got even worst with the recent additions.
- zx14 6y ago> Thiiis really hasn't been my experience with the Python community. Every place I've worked on a Python codebase has done it a different way, and none of them have agreed on what is "pythonic". Exactly my experience from day one. It's a laughable statement that the Python community keeps repeated with almost no basis in reality.
- dmarchand90 6y agoCompared to C++ and Perl I find python code to be really consistent across projects. I agree the language isn't perfect at it but why do anything to make it worse?
- dragonwriter 6y agoThe Zen is not inconsistent with there being different obvious ways to do different, closely related things, and Python has always had those. The Zen is against alternatives for the sake of alternatives, but not for facilities focussed on different use cases. Though as the use cases get more finely divided, the difference is less peeceptible.
- staticautomatic 6y agoI think it’s pretty wild that people are worried about the addition of a coding pattern to a language. What a thing to stress about. Nobody’s taking your Python away from you. I promise everything’s gonna be ok.
- _ZeD_ 6y agothe "problem" (not for me, I personally am pretty "meh" on the feature) is that now you'll have a new pattern to read (and decode) in the others code.
- deleted 6y ago[deleted]
- otabdeveloper4 6y ago> The philosophy of python is there should be only one pythonic way of doing things. That ship has sailed more than a decade ago. (And if we're on a crusade to make Python pythonic again, let's start with the bigger fish - like the sync/async function distinction. Somehow Python managed to fall into the red/blue function trap the hardest.)
- Redoubts 6y ago> the red/blue function trap What should have been done here?
- otabdeveloper4 6y agoPython doesn't need a special keyword to distinguish functions that 'yield' from those that don't. Why should async functions be different?
- antpls 6y agoSame. The only useful addition was type hints. Now, every two releases they add a "language feature". Some library maintainers jump in the bandwagon, and WOOSH! : half the ecosystem depends on CPython to run. Bye Jython, Cython, PyPy, Micropython, etc and bye the code analysis and code transformation tools : all outdated until more funds or voluntary dev are willing to fix them In an ideal world, the community should fork Python 2.7, rename it and add type hints. But that's too late, all the dev time was spent on making libraries compatible only with some recent versions of CPython
- coldtea 6y agoAnd another person might not care at all for type hints, consider them detrimental and against the spirit of pure dynamic Python, and ask for their favorite feature (e.g. async, unicode handling, whatever) to be the "one" feature "they should have added".
- coldtea 6y ago>The philosophy of python is there should be only one pythonic way of doing things. The philosophy of anything (python, unix, etc) is usually just cargo cult early bogus idealism. What happens later is that reality and pragmatism come into play. People don't want simple languages, people want more features.
- mekster 6y agoToo bad ruby didn't take the place of python for popularity but I still see strong fan base around ruby. Maybe people got into python when Google took it for a serious use just like people got into git because of Linus but figured it wasn't the best tool a decade later but the ecosystem is already there it is too late to swap.
- loloquwowndueo 6y ago“ It will take a long time until any library code can safely adapt this new functionality since Python 3.9 will reach its end of life approximately in October 2025” Not true - for example, Black had been requiring python 3.6+ even before 3.5 and older were fully deprecated / unsupported. Just declare the minimum version your library requires in setup.py and let users decide.
- nicoburns 6y agoI can't believe languages are still adding switch/match statements (as opposed to expressions). Has it it not filtered through to everyone yet that everything that can possibly be an expression should be?
- gumby 6y agoHey, it's still a new idea, only introduced in 1958. Give people time to adjust!
- nchammas 6y agoThis idea was briefly addressed in PEP 635 [0]: > _Statement vs. Expression._ Some suggestions centered around the idea of making `match` an expression rather than a statement. However, this would fit poorly with Python's statement-oriented nature and lead to unusually long and complex expressions and the need to invent new syntactic constructs or break well established syntactic rules. An obvious consequence of match as an expression would be that case clauses could no longer have arbitrary blocks of code attached, but only a single expression. Overall, the strong limitations could in no way offset the slight simplification in some special use cases. [0]: https://www.python.org/dev/peps/pep-0635/ https://www.python.org/dev/peps/pep-0635/
- orf 6y agoEither everyone involved with language design has never heard of Lisp or there are inherent tradeoffs with "everything that can possibly be an expression should be" that you are either ignoring or wilfully ignorant of in order to score internet points. I know which one I would bet my money on.
- JadeNB 6y ago> Either everyone involved with language design has never heard of Lisp or there are inherent tradeoffs with "everything that can possibly be an expression should be" that you are either ignoring or wilfully ignorant of in order to score internet points. Entirely seriously, what are the trade-offs? I've heard general defences of it, for example nchammas's quote from van Rossum in a sister post to yours, but they all seem quite general—"it'll complicate things", but in a way that seems only to boil down to "it's unfamiliar and I don't like it." Which, to be fair, is van Rossum's prerogative to say—but it doesn't seem persuasive in light of general language design.
- xchaotic 6y agoSo switch like statements and branched execution are the enemy of caches and especially in the light of recent CPU predictive execution vulnerabilities I guess that is not an ideal syntax. What’s a better way to guide the programs flow based on some input?
- TrianguloY 6y ago"Pattern matching is the switch-case equivalent in Python 3.10 and newer" Well, yes, but actually, no. A switch operator, at least in most other languages, uses comparison to select a branch. Only comparisons are performed (either with each branch or optimized for direct access) but no other side effect. Pattern matching, as with other languages too, tries to 'match' the variable to the pattern. If it succeeds, then the branch is taken and the variables (if any) are assigned, which in python means that they are assigned to the whole current function. This is a big side effect. And that's the main problem, the variable constants. Once you understand the issue it is relatively easy to fix, but for a newcomer this will probably be a few minutes of searching and debugging. Python don't have a switch statement, at least not yet, pattern matching is just another similar feature that can be adapted to work similarly, like the chain of elifs and the lambdas dictionary. However if you want to say otherwise...at least give the warning of the constants at the beginning, not at the end.
- heavenlyblue 6y agoYou can override a comparison operator which means it’s potentially unbounded (not simple) exactly the same way as matching is.
- _ZeD_ 6y agobut 1) it's "opt in" (you need to explicit implement the dunder method) and 2) it's only for specific classes, you cannot change the behavior of 1 == "one"
- dragonwriter 6y ago> it's only for specific classes, you cannot change the behavior of 1 == "one" More clearly because builtins are protected from monkey-patching, you can’t change the behavior of == where both operands are builtins. “Only for specific classes” implies the scope of applicability is much narrower than it is.
- heavenlyblue 6y agoBut you can't do that for pattern matching either.
- bko 6y agoI love how Scala does case match with case classes. You can essentially unpack the attributes of a case class and match on them and put additional guards. Example: bob match { case Person("bob", _) => println("hi bob!") case _ => println("I don't know you") } I think its important that match returns something so you can use outside of a function which this doesn't do. val greeting = bob match { ... } I thought it would be a fun exercise to write case classes in python, kind of like an improved immutable data class with a match that returns. https://mleverything.substack.com/p/scalas-case-class-in-python-with-case-matching-97efb58359b https://mleverything.substack.com/p/scalas-case-class-in-pyt...
- _ZeD_ 6y agothe "problem" with scala and case classes is that it's very cumbersone when you have case classes with 30+ fields (and you'll have it, expecially if they came from some SQL table) and you want to match only a sigle field. as they are positional-only - and you also need to specify all the other placeholders, makes reading the match very difficult
- virtualwhys 6y agoIn the proposed case then why not just: case x:Bar if x.foo = ... => ?
- vram22 6y agoJust for fun, and not meant as an exact match (pun noticed :), I had written a simple simulation of C's switch statement in Python, a while ago: Simulating the C switch statement in Python: https://jugad2.blogspot.com/2016/12/simulating-c-switch-statement-in-python.html?m=0 https://jugad2.blogspot.com/2016/12/simulating-c-switch-stat...
- bengerbil 6y agoOne of the biggest strengths of switch statement, falling through to the next case, unless there's a break, is missing. Of course, I can't think of a good example right now, but I've used it. Of course, I've also used switch statements in do { .. } while (false), so maybe I just need to be voted off the island.
- sam_bristow 6y agoFalling through case statements bydefault has been the cause of so many bugs over the years. Fall-through can be a useful behaviour, but it's definitely a foot-gun.
- cagey 6y ago13 days ago: https://news.ycombinator.com/item?id=26533270 https://news.ycombinator.com/item?id=26533270
- Ambolia 6y agoLooks powerful, but really messy and full of corner cases and gotchas. I hope they rethink this before releasing it as definitive.
- INTPenis 6y agoIn practice I never try to replicate switch/case in Python but prefer what the author lists as "Dictionary" method. Namely matching an item in a dictionary based on either key or perhaps more advanced matching a value inside the dict. Maybe even using re to match it. Either way, I find using a dictionary is the most Pythonic and clean way to do it. Defining the actions first, how to match them and anything else they might need.
- sidpatil 6y agoI believe this is more generally known as table-driven methods, and I also enjoy using them. They feel more ergonomic than conditional statements, and they're also more flexible—you can dynamically modify the conditions and actions by modifying the data structure which contains them.
- everyone 6y agoBreaks are always automatically added? Well that sucks, It can be very useful to do one thing for several cases in a switch statement.
- everyone 6y agoRandom question. What is meant to be the benefit of not explicitly writing down types in python? I have used C, C++, GL, and C# most of my career, but recently I have been helping a friend of mine who is learning to code with her python assignments. Things still have types when the code runs, and type errors can cause all sorts of bugs and problems, but the types are not actually written down by you in the code so u have to remember them all. It just seems to add so much more mental load on the programmer + potential for weird hard to find bugs not being caught by compiler and slipping under the radar. It seems objectively worse to me. But I assume there is supposed to be some benefit. What is it supposed to be? PS Bonus comment: whitespace controlling the flow of the program? Lets make characters that are invisible really important to how the program runs. Thats just plain dumb, that could only be the result of a weird fetish of the originator of the language.
- growt 6y agoWhat actually happens is that the variable REGION_EU will now contain the string "NA" and the case will match! Isn't this the kind of unintuitive behavior that php got criticized for all this time?