Explain Codes LogoExplain Codes Logo

Replacements for switch statement in Python?

python
switch-alternatives
match-case
control-structures
Alex KataevbyAlex Kataev·Aug 3, 2024
TLDR

In Python, one could replicate a switch-case scenario with a dictionary mapping. Here, keys are mapped to functions or lambdas. Each matched key triggers the execution of its associated callable value.

def perform_action(action): return { 'case1': lambda: "Action for case 1", 'case2': lambda: "Action for case 2", 'default': lambda: "Default action", }.get(action, lambda: "Default action")() # Use the function print(perform_action('case1')) # Showtime: Action for case 1. Beware, it's hot!

In this example, we use lambda for spontaneously firing the respective actions. This technique makes your case handling clean, neat, and somewhat classy.

Pythonic switch alternatives: An overview

Before Python 3.10, some developers used cascaded if-elif-else chains to mimic sequential checks, while more paragons used dictionary mappings to strike it crisp and direct.

Dictionary mappings: A versatile approach

Using a dictionary to mimic a switch handles multiple cases using pairwise keys and functions. You can use tuples for multiple variables assignments. This way, complex switch-like situations can be slimmed neatly, thereby evading the nestlings of conditional statements.

action_dispatcher = { ('option1', 'variant1'): handle_option1_variant1, # Because why not? ('option2', 'variant2'): handle_option2_variant2, # Bake some cookies maybe? # so on... }

Invoke the desired function like so:

action = ('option1', 'variant1') action_dispatcher.get(action, default_function)() # Make it rain func-fetti!

New kid on the block: Python 3.10's match-case

Taking a leap from PEP 634, match-case is, arguably, more powerful and versatile than the traditional switches. It supports multi-value patterns, nested sequences, type patterns, and even sudoku (joking, don't try).

match sequence: case [x, y, *rest]: handle_xy_rest(x, y, rest) case _: # The infamous "Talk to the hand" statement. handle_default()

Making the most of match-case

User commands tailored to fit

For user commands, a match-case can differentiate between innocent strings, undercover types, and the complex data structures.

Color me surprised

match can handle colors like COLOR.RED without breaking a sweat, unlike its if-elif cousin.

Can match do data?

When matching data records, match lends a hand to ignore or tackle additional, missing fields, or even extra keys in dictionaries.

The devil is in the details: Control structures dissected

Polymorphism in disguise

Using inline lambdas for quick and simple conditional responses or full-fledged functions for complex logic can substitute classes with operations polymorphically.

match mastery

The match-case statement can handle complicated checks neatly. However, with great power comes greater responsibility to avoid string pattern matching to prevent errors. When using this for dynamic data structures, it can pragmatically ignore or include undefined keys in dictionaries.

if-elif-else has still got it

Even after all these advancements, never downplay the simplicity of the good old if-elif-else sequence. Where you have a lesser number of conditions, or the logic is too dense, or fall-through is vital, if-elif-else is your guy.

Safe shot with match-case

While developing a match-case statement, having a case _ is a good practice. Failing to include this statement, you run the risk of silent failures. So remember, case _ is the net that catches the unhandled cases. It's your safety parachute if no patterns are matched.