Switch/Case In Python

The switch or case statement is a programming feature found in many programming languages that allows you to control the flow of your program based on the value of a variable or an expression. Python does not have a switch/case statement and there’s no satisfactory answer as to why this is the case.

The official answer shows a work around but does not explain why support for switch case was not added. Attempts have been made to have a switch or case statement added to Python as you can see in this PEP and this one but switch doesn’t appear to be popular so both proposals were rejected.

Alternatives

Here is a simple example. Let’s suppose you want to return a value based on an argument that is passed to a function. You could do it this way:

Using an if...elif chain:

def number_to_string(argument):
    if argument == 0:
        return "zero"
    elif argument == 1:
        return "one"
    elif argument == 2:
        return "two"
    else:
        return "nothing found"

For simple situations, a sequence of if ... elif ..elif ..else as you can see above works pretty well.

Dictionary dispatch

A more Pythonic way to implement the switch in Python is to use a dictionary mapping technique called a dictionary dispatch:


def number_to_string(argument):
    switcher = {
        0: "zero",
        1: "one",
        2: "two",
    }
    func = switcher.get(argument, "nothing found")
    return func

Here, you create switcher, a dictionary mapping of numbers and their string versions. Next, get a value from the dictionary and assign the result into func and return that result.

The above can be made more concise:

def number_to_string(argument):
    return {
        0: "zero",
        1: "one",
        2: "two",
    }.get(argument, "nothing found")

Let’s try a more practical example. If, for some reason you were building your own Calendar month_name() method, this is how you might do it, using the usual if..elif as well as using dictionary dispatch:

month = int(input("Enter a number"))

# if...elif way:
def switcher(month):
    if month == 1:
        return "January"
    elif month == 2:
        return "February"
    elif month == 3:
        return "March"
    elif month == 4:
        return "April"
    elif month == 5:
        return "May"
    elif month == 6:
        return "June"
    elif month == 7:
        return "July"
    elif month == 8:
        return "August"
    elif month == 9:
        return "September"
    elif month == 10:
        return "October"
    elif month == 11:
        return "November"
    elif month == 12:
        return "December"

    return "Invalid month selected"

# dictionary dispatch way:
def dict_switcher(month):
    return {
        1: "January",
        2: "February",
        3: "March",
        4: "April",
        5: "May",
        6: "June",
        7: "July",
        8: "August",
        9: "September",
        10: "October",
        11: "November",
        12: "December",
    }.get(month, "Invalid month selected")

Because everything in Python is an object, we can also use dictionary dispatch to map functions to case values:

def zero():
    return "zero"

def one():
    return "one"

def two():
    return "two"

def numbers_to_strings(argument):
    switcher = {
        0: zero,
        1: one,
        2: two,
    }
    func = switcher.get(argument, lambda: "nothing")
    return func()

The code above maps the functions zero(), one() and two() to the case values 0, 1 and 2 respectively. The example above is very simple, but this technique can be used to dispatch more complicated procedures.

What’s going on here?

When numbers_to_strings() is called with an integer as an argument, the switcher dictionary is created and .get() is used to return the function that corresponds to the integer argument if present. If nothing is found, an anonymous function is returned instead. The function that corresponds to the key is assigned to func and the return line calls that function to execute it.

These steps can be made more concise by chaining everything together:

def func_dict_switcher(argument):
    return {
        0: zero,
        1: one,
        2: two,
    }.get(argument, lambda: "nothing")()

Here’s a real world example, making a state machine using functions:

def dict_dispatch(operator, x, y):
    return {
        'add': lambda: x + y,
        'sub': lambda: x - y,
        'mul': lambda: x * y,
        'div': lambda: x / y,
    }.get(operator, lambda: None)()

Conclusion

You’ve seen how to implement dictionary dispatch as a way to emulate the Switch/Case statement found in other programming languages. Thank you for reading.