67

Please explain why Python does not have the switch-case feature implemented in it.

mattst
  • 13,340
  • 4
  • 31
  • 43
T1412
  • 705
  • 1
  • 5
  • 12
  • 3
    They are not very helpful. It is safer to stick with `if... elif` than `switch`. They lead to horrible bugs if you are not careful. – Unni Oct 12 '17 at 03:48
  • For a workaround you can refer to [Is there any value to a Switch / Case implementation in Python?](https://stackoverflow.com/q/5440990/6521116) – LF00 Oct 12 '17 at 03:52
  • Related post - [Replacements for switch statement in Python?](https://stackoverflow.com/q/60208/465053) – RBT Jul 26 '18 at 06:11
  • 4
    I couldn't disagree more with Unni. Maybe bad programmers can't use switch effectively, but I personally have not had any major issues with them. It's way more cumbersome and significantly less pleasant to write and read a bunch of ```if... elif elif elif elif elif``` – default123 Dec 03 '20 at 14:46

7 Answers7

78

Update 2021:

New match-case syntax, which goes far beyond the capabilities of the traditional switch-case syntax, was added to Python in version 3.10. See these PEP documents:


We considered it at one point, but without having a way to declare named constants, there is no way to generate an efficient jump table. So all we would be left with is syntactic sugar for something we could already do with if-elif-elif-else chains.

See PEP 275 and PEP 3103 for a full discussion.

Roughly the rationale is that the various proposals failed to live up to people's expections about what switch-case would do, and they failed to improve on existing solutions (like dictionary-based dispatch, if-elif-chains, getattr-based dispatch, or old-fashioned polymorphism dispatch to objects with differing implementations for the same method).

mattst
  • 13,340
  • 4
  • 31
  • 43
Raymond Hettinger
  • 216,523
  • 63
  • 388
  • 485
  • 6
    `case 1:` is pretty constant, but without *named* constants, you'd have to use magic numbers everywhere, and we don't want a syntax construct that encourages magic numbers. – user2357112 Oct 12 '17 at 04:00
  • 3
    improved readability is among the most important benefits of using `switch` — when you say "we would be left with syntactic sugar" => yes, and that's mostly what people are asking for — if you're wary of not improving performance (efficient jump table), well, someone who's after performance would probably not use Python in the first place (otherwise this guy has a problem), so I wouldn't consider it as a major dealbreaker. – Jivan Jun 13 '20 at 18:50
  • 4
    I came to this question to find out why Python doesn't have switch-case and now I need to find out why you also cannot declare named constants! – Ben Smith Jan 21 '21 at 16:07
14

There is literally a section in the docs to answer this. See below:

Why isn’t there a switch or case statement in Python?

TL;DR: existing alternatives (dynamic dispatch via getattr or dict.get, if/elif chains) cover all the use cases just fine.

wim
  • 338,267
  • 99
  • 616
  • 750
  • 10
    they cover all the use cases just fine, sure, in an ugly, unintuitive and hard-to-read way that eerily differs from virtually any other language in the world, but yes... – Jivan Jun 13 '20 at 18:53
  • 7
    really I don't see how there's even an excuse for a general-purpose language not implementing `switch` (we're not even talking advanced pattern matching ; just a plain-ol', dumb-as-f** switch) — that should be table-stakes, period, no discussion to have. the fact that it's even a matter of debate is something that is beyond me – Jivan Jun 13 '20 at 18:55
9

Update 2021: case introduced in Python 3.10

Structural pattern matching is included in Python 3.10 released in October 2021.

Here is the generic syntax

match subject:
    case <pattern_1>:
        <action_1>
    case <pattern_2>:
        <action_2>
    case <pattern_3>:
        <action_3>
    case _:
        <action_wildcard>

and here is a simple example

def http_error(status):
    match status:
        case 400:
            return "Bad request"
        case 404:
            return "Not found"
        case 418:
            return "I'm a teapot"
        case _:
            return "Something's wrong with the Internet"
divenex
  • 15,176
  • 9
  • 55
  • 55
6
def f(x):
    return {
        1 : 'output for case 1',
        2 : 'output for case 2',
        3 : 'output for case 3'
    }.get(x, 'default case')   

You can use this as switch case in python and if condition not match it will return default if condition not match

VincenzoC
  • 30,117
  • 12
  • 90
  • 112
vedant patel
  • 85
  • 1
  • 3
2

I remembered in ancient time, an inexperienced Larry Walls said that Perl doesn't need case switch construct because it can be done the same way with: "if - elif - elif .... else". Back then Perl was nothing more but a mere scripting tool for hacker kiddies. Of course, today's Perl has a switch construct.

It's not unexpected that over some decades later, the new generation kids with their new toys are doomed to repeat the same dumb statement.

It's all about maturity, boys. It will eventually have a case construct. And when python has matured enough as a programming language, like FORTRAN/Pascal and C and all languages derived from them, it will even have a "goto" statement :)

BTW. Usually, case switch translated to asm as indirect jump to list of address of respective cases. It's an unconditional jump, means far more efficient than comparing it first (avoiding branch misprediction failure), even in just a couple cases it considered as more efficient. For a dozen or more (up to hundreds in code snippet for a device driver) the advantage of the construct is unquestionable. I guess Larry Walls didn't talk assembly back then.

0

Actually, Python does not have a switch case, and you need to use the Class method which is explained somehow like this.

class PythonSwitch:
   def day(self, dayOfWeek):

       default = "Incorrect day"

       return getattr(self, 'case_' + str(dayOfWeek), lambda: default)()

  def case_1(self):
       return "monday"



   def case_2(self):
       return "tuesday"



   def case_3(self):
       return "wednesday"



   def case_4(self):
      return "thursday"



   def case_5(self):
       return "friday"



   def case_7(self):
       return "saturday"

my_switch = PythonSwitch()

print (my_switch.day(1))

print (my_switch.day(3))def case_6(self):
    return "sunday"



my_switch = PythonSwitch()

print (my_switch.day(1))

print (my_switch.day(3))

But this is not good way and python documentation suggest you use to Dictionary method.

def monday():
    return "monday"     
def tuesday():
    return "tuesday"  
def wednesday():
    return "wednesday"
def thursday():
    return "thursday"
def friday():
    return "friday"
def saturday():
    return "saturday"
def sunday():
    return "sunday"
def default():
    return "Incorrect day"

switcher = {
    1: monday,
    2: tuesday,
    3: wednesday,
    4: thursday,
    5: friday,
    6: saturday,
    7: sunday
    }

def switch(dayOfWeek):
    return switcher.get(dayOfWeek, default)()

print(switch(3))
print(switch(5))

Instead of match the style which does not include default value. https://docs.python.org/3.10/whatsnew/3.10.html#pep-634-structural-pattern-matching

def http_error(status):
match status:
    case 400:
        return "Bad request"
    case 404:
        return "Not found"
    case 418:
        return "I'm a teapot"
    case _:
        return "Something's wrong with the internet"

But in 2020 there is new 'Enum-based Switch for Python''https://pypi.org/project/enum-switch/'

from enum import Enum
from enum_switch import Switch

class Color(Enum):
    RED = 1
    GREEN = 2
    BLUE = 3

class MySwitch(Switch):
    def RED(self):
        return "Apple"

    def GREEN(self):
        return "Kiwi"

    def BLUE(self):
        return "Sky"

switch = MySwitch(Color)

print(switch(Color.RED))

Apple

If MySwitch was miss­ing one of those "han­dler­s" for the Enum val­ues? That's an ex­cep­tion. If you don't want to de­fine them al­l? Do a de­fault­() there.

-1

Why would any modern language support a switch/case statement?

It is like the goto statement. It is an outdated construct, that when following SOLID and good design pratices, just shouldn't get used. It was useful at one time, but as we matured in SOLID and other design patterns, it became clear that it was less effective.

I am a C# developer primarily, but I hit python, TypeScript, and other languages now and then and I haven't used Switch/case in almost a decade. Every single opportunity to use switch case leads to bad cade that is not SOLID and has high Cyclomatic complexity.

Python mentions using a dictionary, which is right in line with what I recommend in C#. https://www.rhyous.com/2017/10/19/eliminating-cylclomatic-complexity-by-replacing-switchcase-with-a-method-or-a-dictionary/

Rhyous
  • 6,510
  • 2
  • 44
  • 50