Home / Blog /
The essential guide to Python switch statements
//

The essential guide to Python switch statements

//
Tabnine Team /
4 minutes /
May 17, 2021

Switch statements are one of the building blocks of logic in code. It’s a way to create selection control in a standardized format that is much more condensed than your typical if-else option. In most cases, a switch statement is faster to code and run when compared to if-else, when pitched in contrast against a switch statement.

Unlike every other popular programming language, Python doesn’t have a switch or case statement functionality available. However, all this changed with Python 3.10. Anything older than Python 3.10 does not support switch statements and therefore the contents of this article will not work on a majority of versions.

For context, at the time of writing, Python 3.10 is still in the testing phase and remains in an early developer preview release. Nevertheless, the ability to use switch statements is an exciting and major development for Python and Python developers.

Without further ado, let’s get right into it.

What is a switch statement (and why should you know it)?

A switch statement is a set of conditional tests that allows the developer to direct the course of the program based on a set of scenarios and variables.

On the surface, a switch statement looks somewhat similar to an if statement, but with structural and syntax differences. For example, an if statement in Python looks something like this:

 a = 10
 b = 20
 if a > b:
 print("a is greater than b")

The equivalent of else-if in Python looks something like this:

 a = 10
 b = 20
 if a > b:
  print("a is greater than b")
 elif a == b:
  print("a is equal to b")

And finally, the default final else to provide a catch all clause for when none of the cases match:

 a = 10
 b = 20
 if a > b:
  print("a is greater than b")
 elif a == b:
  print("a is equal to b")
 else:
  print("b is greater than a")

The shorthand of if-else in Python looks something like this:

 a = 10
 b = 20
 print("a is greater than b") if a > b else print("a is equal to b") elif a == b else print("b is greater than a")

As you can see, things are already starting to get complicated. On the surface, everything looks quite simple. But if you look at it from an ease of readership and comprehension, having more than one or two sets of if statements can already begin to clog up our code.

When there are too many if-else statements in a block of code, it can feel like reading a run-on sentence. The longer the sentence, the harder it is to keep all the information in your mind and comprehend what it’s trying to tell you.

This is where switch statements in Python come in.

Switch statement in Python

Switch statements in Python are defined by two things: match and case. match sets up the scene and tells Python that the following block of code will be a switch statement. case sets up Python with what to do if the conditions are met.

Here is an example:

 localhost = "3000"
 ​
 match localhost:
     case "80":
         print("localhost:80")
         do_something_http()
     case "8080":
         print("localhost:8080")
         do_something_httpalt()
     case "443":
         print("localhost:443")
         do_something_secure()
     case "3000":
         print("localhost:3000")
         do_something_localhost()
     case "80":
         print("localhost:4200")
         do_something_webpack()
     case _:
         print("localhost not found")

What’s happening here is that each block gets evaluated. If the case matches exactly, then the following block of code gets executed. While this can be achieved in the same manner with a series of if-else statements, the removal of comparison conditionals (e.g. if localhost == "80" etc.) repeated on multiple instances makes it “cleaner”.

An underscore _ is used to signify the default, catch-all case when nothing satisfies the given parameters. If no case _: is given, you will run into an error if nothing matches.

Here is another example of improved code readability with Python switch statement:

 match (product, category):
     case ("milk", "dairy"):
         print("15% discount today only!")
     case ("lettuce", "vegetables")
         print("veggies are good for you")
     case ("beef", "butchery")
         print("mmmm iron")
     case _:
         print("you didn't add anything")
 

You can pass multiple arguments into the switch to be compared against the cases. The sequence and length of these arguments is entirely up to you and there is no restriction in Python.

In addition to arguments, you can also pass in objects like this:

 match user:
     case User(admin=False):
         print("You are not authorized")
     case User(region="NA"):
         print("You are from the North America!")
     case User():
         print("This is a customer somewhere else")
     case _:
         print("Error: Not a user!")

User() is an object with data attached to it. For example, by adding admin=False and region="US" in between the parenthesis, you are creating a condition for the switch statement to evaluate.

The examples so far have been based on static values. What if we wanted to make our switch statements a bit more dynamic in Python?

Here is the syntax example of how to write it:

 REGION = "NA"
 ​
 match user:
     case User(admin=False):
         print("You are not authorized")
     case User(region=REGION):
         print("You are from the {REGION}")
     case User():
         print("This is a customer somewhere else")
     case _:
         print("Error: Not a user!")

In the example above, {REGION} is dynamically pulled into the print() statement, while also being a parameter for matching in User(region=REGION).

Based on the above Python switch patterns, we can also increase the complexity of the condition by adding more parameters. Here is another example:

 class Region(str, Enum):
     AFRICA = "AF"
     ASIA = "AS"
     EUROPE = "EU"
     NORTH_AMERICA = "NA"
     OCEANIA = "OC"
     SOUTH_AND_CENTRAL_AMERICA = "SA"
 ​
 match user:
     case User(admin=False, region=region):
         print(f"This is a customer in {region}")
     case _:
         print("Error: Not a user!")

Now that we’ve got the basics down, what about conditionals in Python switch statements?

The same match and case structure still applies. The only main difference is how you write your conditional after the case keyword.

Here is a quick example of what this looks like:

 match items:
     case [Item() as i1, Item() as i2] if i1.name == i2.name:
         print(f"Discount applied: x2 {i1.name}")
     case [Item(), Item()]:
         print(f"No 2 for 1 deal. Item not the same.")
     case _:
         print("Received something else")

The first part of the conditional is encased around [] to set up the arguments of the conditional. The second part is an if statement that allows you to compare the arguments against each other. If the if condition is met, then the case is executed.

While this may seem like you’re just writing another if-else statement, a switch case structure in Python is much easier to debug in the long run, while also giving you the flexibility to match other cases without the need of an explicit conditional.

Conclusion

While switch statements in Python are still in its experimental testing phase, the expected release date is October 10 2021 — so not too far off. Everyone is expected to migrate out of version 3.9 by mid 2022 as full support for that version is being discontinued.

Overall, pattern matching in Python switch statements is quite easy to understand once you have the syntax and general structure of how it works.