Python Case Statement: How To Create Switch-Case in Python?

Switch case in Python is a control structure that compares a value against multiple patterns and executes code based on the matching pattern. Introduced in Python 3.10 as the match-case statement, it replaces complex if-elif chains with elegant pattern matching.

Python programming has changed a lot. For years, people wanted something like the switch statements in other languages.

They finally got it in 2021 with Python 3.10.

But first, let’s understand what all this means.

What Is a Switch Statement?

Think of a vending machine. You press button A, you get chips. Press button B, you get a candy bar. Press button C, you get a drink.

That’s what a switch statement does in programming. You give it a value, and it does different things based on that value.

It’s like asking: “What number is this?” And then doing something different for each answer.

Python Switch-Case Statement Before Python 3.10

Python programmers felt left out. Other languages had switch statements. Python didn’t.

So they got creative. They found ways to work around this problem.

Method 1: Using If-Elif-Else

This was the most common way. It looks like this:

def check_day(day):
    if day == 1:
        return "Monday"
    elif day == 2:
        return "Tuesday"  
    elif day == 3:
        return "Wednesday"
    elif day == 4:
        return "Thursday"
    elif day == 5:
        return "Friday"
    elif day == 6:
        return "Saturday"
    elif day == 7:
        return "Sunday"
    else:
        return "Invalid day"

print(check_day(3))  # Shows: Wednesday

This works fine for simple cases. But imagine having 20 or 30 conditions. It gets messy fast.

The code becomes long. It’s hard to read. And it’s easy to make mistakes.

Method 2: Using a Dictionary

Smart programmers came up with another idea. They used dictionaries like a switch statement:

def check_day(day):
    days = {
        1: "Monday",
        2: "Tuesday",
        3: "Wednesday",
        4: "Thursday",
        5: "Friday",
        6: "Saturday",
        7: "Sunday"
    }
    return days.get(day, "Invalid day")

print(check_day(3))  # Shows: Wednesday

This is cleaner. But it only works well for simple cases.

What if you need to run different code for each case? It gets complicated again.

Method 3: Using Functions in Dictionaries

Some people put functions in dictionaries:

def say_hello():
    print("Hello!")

def say_goodbye():
    print("Goodbye!")

def say_how_are_you():
    print("How are you?")

actions = {
    1: say_hello,
    2: say_goodbye,
    3: say_how_are_you
}

choice = 1
if choice in actions:
    actions[choice]()  # This calls the function

This works but it’s hard to understand for beginners. And you need to create many small functions.

After Python 3.10: The Match-Case Statement

In October 2021, Python 3.10 changed everything. They added the match-case statement.

It looks much cleaner. It’s easier to understand. And it does much more than a simple switch statement.

Basic Match-Case Example

Here’s how the new way looks:

def check_day(day):
    match day:
        case 1:
            return "Monday"
        case 2:
            return "Tuesday"
        case 3:
            return "Wednesday"
        case 4:
            return "Thursday"
        case 5:
            return "Friday"
        case 6:
            return "Saturday"
        case 7:
            return "Sunday"
        case _:
            return "Invalid day"

print(check_day(3))  # Shows: Wednesday

See how clean that is? The match keyword checks the value. Each case is one possible match.

The _ (underscore) is special. It matches anything that didn’t match before. It’s like the “else” in if-else.

Multiple Values in One Case

You can match multiple values at once:

def check_type(value):
    match value:
        case 1 | 2 | 3:
            return "Small number"
        case 4 | 5 | 6:
            return "Medium number"
        case 7 | 8 | 9:
            return "Large number"
        case _:
            return "Not a single digit"

print(check_type(2))  # Shows: Small number
print(check_type(8))  # Shows: Large number

The | symbol means “or”. So case 1 | 2 | 3: means “if it’s 1 or 2 or 3”.

Matching Patterns

Here’s where it gets really cool. You can match patterns, not just values:

def describe_point(point):
    match point:
        case (0, 0):
            return "Origin"
        case (0, y):
            return f"On Y-axis at {y}"
        case (x, 0):
            return f"On X-axis at {x}"
        case (x, y):
            return f"Point at ({x}, {y})"
        case _:
            return "Not a point"

print(describe_point((0, 0)))    # Shows: Origin
print(describe_point((0, 5)))    # Shows: On Y-axis at 5
print(describe_point((3, 4)))    # Shows: Point at (3, 4)

This is pattern matching. Python looks at the shape of your data and matches it.

Working with Lists

You can match list patterns too:

def analyze_list(data):
    match data:
        case []:
            return "Empty list"
        case [x]:
            return f"One item: {x}"
        case [x, y]:
            return f"Two items: {x} and {y}"
        case [x, y, z]:
            return f"Three items: {x}, {y}, and {z}"
        case [x, *rest]:
            return f"First is {x}, and {len(rest)} more items"

print(analyze_list([]))          # Shows: Empty list
print(analyze_list([10]))        # Shows: One item: 10
print(analyze_list([1, 2]))      # Shows: Two items: 1 and 2
print(analyze_list([1, 2, 3, 4])) # Shows: First is 1, and 3 more items

The *rest captures all remaining items in the list.

Adding Conditions with Guards

You can add extra conditions using if:

def check_age(age):
    match age:
        case x if x < 0:
            return "Invalid age"
        case x if x < 13:
            return "Child"
        case x if x < 20:
            return "Teenager"
        case x if x < 60:
            return "Adult"
        case _:
            return "Senior"

print(check_age(8))   # Shows: Child
print(check_age(15))  # Shows: Teenager
print(check_age(35))  # Shows: Adult

The if part is called a “guard”. It adds an extra check to the pattern.

Working with Classes

Match-case works great with classes too:

class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age

class Cat:
    def __init__(self, name, age):
        self.name = name
        self.age = age

def describe_pet(pet):
    match pet:
        case Dog(name=name, age=age) if age < 2:
            return f"{name} is a puppy"
        case Dog(name=name, age=age):
            return f"{name} is a {age}-year-old dog"
        case Cat(name=name, age=age) if age < 1:
            return f"{name} is a kitten"
        case Cat(name=name, age=age):
            return f"{name} is a {age}-year-old cat"
        case _:
            return "Unknown pet"

my_dog = Dog("Rex", 1)
my_cat = Cat("Whiskers", 3)

print(describe_pet(my_dog))  # Shows: Rex is a puppy
print(describe_pet(my_cat))  # Shows: Whiskers is a 3-year-old cat

When Should You Use the Python Case Statement?

Match-case is powerful, but you don’t always need it. Here’s when to use it:

  1. When you have many conditions: If you have more than 3-4 elif statements, consider match-case.
  2. When you’re checking patterns: If you need to check the structure of data, match-case is perfect.
  3. When working with data types: If you need to handle different types of data differently.
  4. When unpacking data: If you need to get values from tuples, lists, or objects.

Simple Rules for Python Match-Case

Here are the main rules to remember:

  1. Start with match followed by what you want to check
  2. Each case is one possible match
  3. Use _ for the default case (like else)
  4. Use | to match multiple values
  5. Use if to add extra conditions
  6. Variables in patterns capture values

Common Python Case Statement Mistakes to Avoid

People make these mistakes when learning Python match-case:

Mistake 1: Forgetting the Default Case

# Bad - no default case
def get_grade(score):
    match score:
        case 90:
            return "A"
        case 80:
            return "B"
        case 70:
            return "C"
    # What if score is 85? Nothing happens!

# Good - has default case
def get_grade(score):
    match score:
        case 90:
            return "A"
        case 80:
            return "B"
        case 70:
            return "C"
        case _:
            return "Other grade"

Mistake 2: Using Constants Wrong

# This doesn't work as expected
RED = 1
BLUE = 2

color = 1

match color:
    case RED:    # This creates a new variable named RED!
        print("It's red")
    case BLUE:
        print("It's blue")

# Use dotted names for constants
class Colors:
    RED = 1
    BLUE = 2

match color:
    case Colors.RED:    # This works correctly
        print("It's red")
    case Colors.BLUE:
        print("It's blue")

Mistake 3: Order Matters

# Bad - general case comes first
def check_number(x):
    match x:
        case _:           # This catches everything!
            return "A number"
        case 0:           # This never runs
            return "Zero"

# Good - specific cases first
def check_number(x):
    match x:
        case 0:           # Check specific values first
            return "Zero"
        case _:           # General case last
            return "A number"

Summary: What We’ve Learned

Python’s journey to get a switch-case statement has been long. But the wait was worth it.

Before Python 3.10, we had to use:

  • Long if-elif-else chains
  • Dictionary mappings
  • Complex workarounds

Now with match-case, we can:

  • Write cleaner code
  • Match complex patterns
  • Handle different data types easily
  • Unpack values while matching
  • Add conditions to our patterns

Match-case is more than just a switch statement. It’s a powerful pattern matching system. It makes Python code easier to read and write.

Remember: You don’t always need match-case. For simple conditions, if-else is fine. But when things get complex, match-case can make your code much better.

The future of Python is bright. Features like match-case show that Python keeps getting better while staying simple to use.

Now you know how to use match-case in Python. Go try it in your own code!

Pankaj Kumar
Pankaj Kumar

I have been working on Python programming for more than 12 years. At AskPython, I share my learning on Python with other fellow developers.

Articles: 210