Most of the answers here are pretty old, and especially the accepted ones, so it seems worth updating.
First, the official Python FAQ covers this, and recommends the elif
chain for simple cases and the dict
for larger or more complex cases. It also suggests a set of visit_
methods (a style used by many server frameworks) for some cases:
def dispatch(self, value):
method_name = 'visit_' + str(value)
method = getattr(self, method_name)
method()
The FAQ also mentions PEP 275, which was written to get an official once-and-for-all decision on adding C-style switch statements. But that PEP was actually deferred to Python 3, and it was only officially rejected as a separate proposal, PEP 3103. The answer was, of course, no—but the two PEPs have links to additional information if you're interested in the reasons or the history.
One thing that came up multiple times (and can be seen in PEP 275, even though it was cut out as an actual recommendation) is that if you're really bothered by having 8 lines of code to handle 4 cases, vs. the 6 lines you'd have in C or Bash, you can always write this:
if x == 1: print('first')
elif x == 2: print('second')
elif x == 3: print('third')
else: print('did not place')
This isn't exactly encouraged by PEP 8, but it's readable and not too unidiomatic.
Over the more than a decade since PEP 3103 was rejected, the issue of C-style case statements, or even the slightly more powerful version in Go, has been considered dead; whenever anyone brings it up on python-ideas or -dev, they're referred to the old decision.
However, the idea of full ML-style pattern matching arises every few years, especially since languages like Swift and Rust have adopted it. The problem is that it's hard to get much use out of pattern matching without algebraic data types. While Guido has been sympathetic to the idea, nobody's come up with a proposal that fits into Python very well. (You can read my 2014 strawman for an example.) This could change with dataclass
in 3.7 and some sporadic proposals for a more powerful enum
to handle sum types, or with various proposals for different kinds of statement-local bindings (like PEP 3150, or the set of proposals currently being discussed on -ideas). But so far, it hasn't.
There are also occasionally proposals for Perl 6-style matching, which is basically a mishmash of everything from elif
to regex to single-dispatch type-switching.
switch
is actually more "versatile" than something returning different fixed values based on the value of an input index. It allows for different pieces of code to be executed. It actually does not even need to return a value. I wonder if some of the answers here are good replacements for a generalswitch
statement, or only for the case of returning values with no possibility of executing general pieces of code. – sancho.s ReinstateMonicaCellio