Sentry Answers>Python>

Switch-case statement equivalents in Python

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):

Click to Copy
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:

Click to Copy
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:

Click to Copy
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:

Click to Copy
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:

Click to Copy
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:

Click to Copy
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:

Click to Copy
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

Click to Copy
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

Click to Copy
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:

Click to Copy
if hour in switch_dict.keys(): switch_dict[hour]() else: print("An hour of no consequence.")
  • Sentry BlogPython Performance Testing: A Comprehensive Guide
  • Syntax.fmListen to the Syntax Podcast
  • Sentry BlogLogging in Python: A Developer’s Guide
  • Syntax.fm logo
    Listen to the Syntax Podcast

    Tasty treats for web developers brought to you by Sentry. Get tips and tricks from Wes Bos and Scott Tolinski.

    SEE EPISODES

Considered “not bad” by 4 million developers and more than 100,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.

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