Switch-case statement equivalents in Python

David Y.

The Problem

Many imperative programming languages support a switch or case control structure, which allows programmers to specify an arbitrary number of alternative code blocks to execute, depending on the value of a variable or expression. For example (pseudocode):

switch (hour) { case 13: print("It's one o'clock in the afternoon, time for lunch."); break; case 17: print("The workday is finished!"); break; case 8: print("Time for breakfast!"); break; default: print("An hour of no consequence."); break; }

Does Python have something equivalent?

The Solution

The match-case statement was introduced in Python 3.10, providing an official version of this control structure for the first time. The variable or expression provided to match is tested against each pattern specified in an indented case statement.

We could implement the pseudocode above in Python as follows:

match hour: case 13: print("It's one o'clock in the afternoon, time for lunch.") case 17: print("The workday is finished!") case 8: print("Time for breakfast!") case _: # equivalent to "default case" -- this will be executed if nothing else matches print("An hour of no consequence.")

The above code uses literal values as match patterns, but match-case supports a variety of additional, more complex patterns. Instead of matching literal values, we can use structural patterns to match an object’s type or structure:

match unknown_var: case str(): print("It's a string.") case [int(), str()]: print("It's a sequence of two values, an integer and a string.") case {"Apples": 3, "Oranges": 2}: print("It's a dictionary containing at least two known key-value pairs.") case [_, _, _]: print("It's a sequence of three values of any type.")

There are also capture patterns, which allow us to save and use the value of the matched expression:

match hour: case 13: print("It's one o'clock in the afternoon, time for lunch.") case 17: print("The workday is finished!") case 8: print("Time for breakfast!") case h: # the value of hour is stored in h print(f"The time is {h}")

We can even use structural and capture patterns together:

def count_products(products): match products: case p: print(f"1 product: {p}") case p, q: print(f"2 products: {p} and {q}") case p, q, r: print(f"3 products: {p}, {q} and {r}") count_products(["Apples"]) # will print "1 product: Apples" count_products(["Apples", "Oranges"]) # will print "2 products: Apples and Oranges" count_products(["Apples", "Oranges", "Bananas"]) # will print "3 products: Apples, Oranges, and Bananas"

Patterns can also have if clauses, called guards. For example:

def count_products(products): match products: case p, q if p != q: print(f"Different products") case p, q: print(f"Duplicate products") count_products(["Apples", "Oranges"]) # will print "Different products" count_products(["Apples", "Apples"]) # will print "Duplicate products"

We can also use the logical or operator (|) to include multiple alternative patterns in a single case statement:

match hour: case 9 | 10 | 11 | 12: print("Workday, before lunch") case 13 | 14 | 15 | 16: print("Workday, after lunch")

Further examples are provided in the Python 3.10 release notes.

Alternatives to match-case

Prior to the introduction of match-case in Python 3.10, the following alternatives were often used to emulate switch-case functionality.

if-elif blocks

if hour == 13: print("It's one o'clock in the afternoon, time for lunch.") elif hour == 17: print("The workday is finished!") elif hour == 8: print("Time for breakfast!") else: print("An hour of no consequence.")

Dictionaries with lambdas

switch_dict = { 13: lambda: print("It's one o'clock in the afternoon, time for lunch."), 17: lambda: print("The workday is finished!"), 8: lambda: print("Time for breakfast!") } switch_dict[hour]()

While this method is more syntactically similar to the switch-case statement in other languages than chained elifs, it cannot elegantly support a default case. If such a case is needed, the final line would have to be changed to the following:

if hour in switch_dict.keys(): switch_dict[hour]() else: print("An hour of no consequence.")

Get Started With Sentry

Get actionable, code-level insights to resolve Python performance bottlenecks and errors.

  1. Create a free Sentry account

  2. Create a Python project and note your DSN

  3. Grab the Sentry Python SDK

pip install --upgrade sentry-sdk
  1. Configure your DSN
import sentry_sdk sentry_sdk.init( "https://<key>@sentry.io/<project>", # Set traces_sample_rate to 1.0 to capture 100% # of transactions for performance monitoring. # We recommend adjusting this value in production. traces_sample_rate=1.0, )

Loved by over 4 million developers and more than 90,000 organizations worldwide, Sentry provides code-level observability to many of the world’s best-known companies like Disney, Peloton, Cloudflare, Eventbrite, Slack, Supercell, and Rockstar Games. Each month we process billions of exceptions from the most popular products on the internet.

Share on Twitter
Bookmark this page
Ask a questionJoin the discussion

Related Answers

A better experience for your users. An easier life for your developers.

    TwitterGitHubDribbbleLinkedinDiscord
© 2024 • Sentry is a registered Trademark
of Functional Software, Inc.