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.
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 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.
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.