Does the "switch case" feature exist in python?

Does the "switch case" feature exist in python?

Many will probably say no. And they are not entirely wrong. Because there is nowhere they have seen switch case used in a python program. Indeed, switch case is a conditional feature that exists in most programming languages. In python, this feature was only introduced in python 10 under the name match case.

How does it work?

To understand how switch case works in python, let us go with a simple example.

Imagine that we are asked to create a small automatic script to respond to a user's greeting. The user can say "Hello", "Hi", "Hey" "Good morning", "Good afternoon" or "Good evening". If the program understands the greeting, responds with the same greeting and adds "How are you"? The user can respond with "Good", "Okay", "Well" or "Fine". And then the program welcomes the user and closes. In all cases where the program does not understand the user's answer, it lets him know. We know that this scenario can be solved by the "if, elif, else" as usual. We can do like this :

while True:
    user_answer = input("Talk to me: ")
    if user_answer =="Hello" or user_answer =="Hi" or user_answer == "Hey" or user_answer == "Good morning" or user_answer == "Good afternoon" or user_answer == "Good evening":
        print(f"{user_answer}. How are you?")
    elif user_answer == "Good" or user_answer == "Okay" or user_answer == "Well" or user_answer == "Fine":
        print(f" I am {user_answer}.")
        print("Perfect. Welcome home!")
        break
    else:
        print("I don't undersand")

This code above is correct but it can become complex and difficult to read when there are more cases. Then it is better to use the match case feature.

while True:
    user_answer = input("Talk to me : ")
    match user_answer:
        case "Hello" | "Hi"| "Hey" | "Good morning" | "Good afternoon" |"Good evening":
            print(f"{user_answer}. How are you?")
        case "Good" | "Okay" | "Well" | "Fine":
            print(f" I am {user_answer}.")
            print("Perfect. Welcome home!")
            break
        case _:
            print("I don't undersand")

With the match case, we no longer need to repeat the variable names in the check and the or operator is replaced by the | operator. To handle all other cases not included in the verification, we use the wildcard. In python, we use the underscore _. That is what you can see in case _:

Compared to switch case in many programming languages, the match case is more efficient in Python. It allows the Python language to handle structural pattern matching well. It allows not only to test the values contained in the variables but also the structure of the data constituting these values.

Use match case for structural pattern matching

Suppose we have a list of people and that the information available for each person may vary according to age or occupation.

For example, we have a list of 3 persons. For the first person, we have the name, age, and occupation. For the second person, we know his name, his age and his phone number. For the third person, there is the name, age, job, email, and phone. For those who have an occupation, it is necessary to know the job and the company. If we have to display the details of every person, we can use match case.

person1= {"name":"Paul", "age":20, "phone":0487968521, "occupation":("Developer","Google"), "email":"email@gmail.com"}
person2= {"name":"Peter", "age":16, "phone":0701254862}
person3= {"name":"Patrick", "age":25, "phone":0487968528, "occupation":("Developer","Google")}

person_list= (person1, person2, person3)
for person in persons_list:
    match person:
        case {"name":name, "age":age, "phone":phone, "occupation":(job, company), "email":email }:
            print(f"Name: {name}, Age: {age}, Occupation: {job} at {company}, Email: {email}, Phone: {phone}")
        case _:
            print("Format not supported")

The above code will only display information for persons who have a name, age, occupation, email address and telephone number. All other cases are not supported.

However, if needed, we can display all other cases even if the information is incomplete. We can modify the loop by adding the other cases:

for person in persons_list:
    match person:
        case {"name":name, "age":age, "phone":phone, "occupation":(job, company), "email":email}:
            print(f"Name: {name}, Age: {age}, Occupation: {job} at {company}, Email: {email}, Phone: {phone}")
        case {"name":name, "age":age, "phone":phone, "occupation":(job, company)}:
            print(f"Name: {name}, Age: {age}, Occupation: {job} at {company}, Phone: {phone}")
        case {"name":name, "age":age, "phone":phone}:
            print(f"Name: {name}, Age: {age}, Phone: {phone}")
        case _:
            print("Format not supported")

In this case, the order of testing is very important. It is good to go from the most particular case (i.e. the case with more information and details, i.e. the most unique case) to the most general case. In our example, each person has a name, an age and a phone number. This is the most general case. Therefore, this is the case that should come last in the test. If by mistake we start with the general case, all cases will conform to the general case and nothing special will be displayed.

Add "if" test in match case block

If we want to mention if the person who does not have an occupation is a senior or a junior in the information to be displayed, you can modify the code in two possible ways:

  • Put the "if" test inside the case block.
for person in persons_list:
    match person:
        case {"name":name, "age":age, "phone":phone, "occupation":(job, company), "email":email}:
            print(f"Name: {name}, Age: {age}, Occupation: {job} at {company}, Email: {email}, Phone: {phone}")
        case {"name":name, "age":age, "phone":phone, "occupation":(job, company)}:
            print(f"Name: {name}, Age: {age}, Occupation: {job} at {company}, Phone: {phone}")
        case {"name":name, "age":age, "phone":phone}:
            if age < 18:
                print(f"Name: {name}, Age: {age}, Phone: {phone}, JUNIOR")
            else:
                print(f"Name: {name}, Age: {age}, Phone: {phone}, SENIOR")
        case _:
            print("Format not supported")
  • Include the "if" test in the case verification (same line)
for person in persons_list:
    match person:
        case {"name":name, "age":age, "phone":phone, "occupation":(job, company), "email":email}:
            print(f"Name: {name}, Age: {age}, Occupation: {job} at {company}, Email: {email}, Phone: {phone}")
        case {"name":name, "age":age, "phone":phone, "occupation":(job, company)}:
            print(f"Name: {name}, Age: {age}, Occupation: {job} at {company}, Phone: {phone}")
        case {"name":name, "age":age, "phone":phone} if age < 18:
            print(f"Name: {name}, Age: {age}, Phone: {phone}, JUNIOR")
        case {"name":name, "age":age, "phone":phone} if age >= 18:
            print(f"Name: {name}, Age: {age}, Phone: {phone}, SENIOR")
        case _:
            print("Format not supported")

Conclusion

Note that the match case syntax allows us to avoid embedding too many if else in our code. It, therefore, allows us to simplify our code slightly. It also allows us to browse the data more easily, especially in the case where there are data from different structures.