Case Statement in Python: Best Practices and Alternatives

Categories:
- Written by:
Nathan Rosidi
Mastering case statement in Python with best practices, alternatives, and real-life applications
Case logic in programming refers to making decisions based on values. Python's if-elif-else clauses have always supported this concept. However, Python did not provide a specific case-style syntax for many years.
In this article, we will explore what a case statement in Python is, review different techniques to implement it, and compare their effectiveness.
What is a Case Statement in Python?
Case statements are used to define different paths based on specific conditions. (e.g., x < 1) Python offers various options, such as the if-else statement.
However, writing long if-elif-else chains may swiftly become frantic. The code starts looking like a puzzle rather than a strategy when you correct one condition and another breaks. Here is a simple code to show it.
x = 2
if x == 1:
print("One")
elif x == 2:
print("Two")
elif x == 3:
print("Three")
else:
print("Other")
The switch or case statement was a shortcut for this in other languages. For example, SQL uses case when statements in SQL to handle conditional logic in queries. Python didn’t have one, so many developers simply worked around it by repeatedly writing the same checks for years.
With Python 3.10, the match-case was introduced. This new form of case statement in Python for handling branching logic is neater and involves fewer repetitions compared to the traditional switch-case. Let’s see a simple demonstration of match-case.
x = 2
match x:
case 1:
print("One")
case 2:
print("Two")
case 3:
print("Three")
case _:
print("Other")
But these are not the only ways to handle such logic. We can also use dictionary mappings to simulate case behavior, or apply object-oriented techniques like Classes and Polymorphism when more structure is needed.
Different Techniques to Handle Case Logic in Python
Even without a specific case keyword, Python enables us to build logic based on conditions.
Now let's discover how the same logic can be expressed in multiple ways using various strategies.

Approach 1: If-Elif-Else Chains
In Python, an if-else block is the simplest and fastest way to define conditions. Here is a simple if-elif-else block that defines conditions and returns a discount rate based on the user type.
def get_user_discount(user_type):
if user_type == "student":
return 20
elif user_type == "senior":
return 30
elif user_type == "veteran":
return 25
else:
return 0
print(get_user_discount("student"))
Run the code to see the output.
Since the input meets the "student" condition in the first check, 20 will be returned.
Approach 2: Dictionary Mapping (Simulating a Case Statement in Python)
Another way of defining conditions is by using dictionary mapping. We’ll use the same condition to be able to compare. Here is the code.
def get_user_discount(user_type):
discount_map = {
"student": 20,
"senior": 30,
"veteran": 25
}
return discount_map.get(user_type, 0)
print(get_user_discount("student"))
Here is the output:

Because the "student" key has a value of 20 in the dictionary, this returns 20.
Approach 3: Match-Case (Modern Case Statement in Python, Python 3.10+)
With Python 3.10, a new syntax called match-case was introduced. Let’s use the same example with a match-case. Here is the code.
def get_user_discount(user_type):
match user_type:
case "student":
return 20
case "senior":
return 30
case "veteran":
return 25
case _:
return 0
print(get_user_discount("student"))
This produces the following output:

Because the case "student" matches the input and runs the right block, this outputs 20.
Approach 4: Classes and Polymorphism
By specifying distinct behaviors in distinct classes, object-oriented architecture enables us to manage case logic. When every situation calls for its own set of rules or internal logic, this approach can be helpful.
In the example below, every user type is represented by a class that returns a unique discount rate.
class User:
def get_discount(self):
return 0
class Student(User):
def get_discount(self):
return 20
class Senior(User):
def get_discount(self):
return 30
class Veteran(User):
def get_discount(self):
return 25
def get_user_discount(user):
return user.get_discount()
print(get_user_discount(Student()))
Output:

Because the Student class uses its discount logic to override the base function, this outputs 20.
A Real-World Test: Case Logic in an Uber Data Project

Uber has used this data project during the data science recruitment process. Here, we have different scenarios where we calculate the outcome of each, such as how much the driver would earn from the total bonus.
This is based on the driver being online at least 8 hours, accepting 90% of requests, completing 10 trips, and having a rating of 4.7 or better.
Link to this project: https://platform.stratascratch.com/data-projects/partner-business-modeling
Note: In this article, we will focus only on Scenario 1 of the project.
Data Exploration
Let’s load the dataset and check the first few rows with this code.
import pandas as pd
import numpy as np
df = pd.read_csv('dataset_2.csv')
df.head(10)
Here is the output.

The dataset contains driver data such as the name, trips completed, accept rate, supply hours, and rating.
Scenario 1: Calculating Driver Bonuses Based on Rules
This scenario comes from a real Uber data science project. It focuses on examining how driver bonuses can be calculated based on performance measures from a busy Saturday.
There are two options:
- Option 1: $50 for each driver who is online at least 8 hours, accepts 90% of requests, completes 10 trips, and has a rating of 4.7 or better during the time frame;
- Option 2: $4/trip for all drivers who complete 12 trips and have a 4.7 or better rating.
Next, we have four different questions.
- How much would the total bonus payout be with Option 1?
- How much would the total bonus payout be with Option 2?
- How many drivers would qualify for a bonus under Option 1 but not under Option 2?
- What percentages of drivers online completed less than 10 trips, had an acceptance rate of less than 90%, and had a rating of 4.7 or higher?
We will solve each question by using different case statement approaches in Python.
Question 1: How much would the total bonus payout be with Option 1?
Technique: if-else statements
To find an answer to this question, we will check each driver to see if they meet all four conditions and assign a fixed bonus using if-else logic.
Here is the code.
df.columns = df.columns.str.strip().str.lower().str.replace(' ', '_')
def option_1_bonus(row):
if (
row['supply_hours'] >= 8 and
row['accept_rate'] >= 0.9 and
row['trips_completed'] >= 10 and
row['rating'] >= 4.7
):
return 50
else:
return 0
df['accept_rate'] = df['accept_rate'].str.replace('%', '').astype(float) / 100
df['bonus_option_1'] = df.apply(option_1_bonus, axis=1)
total_option_1 = df['bonus_option_1'].sum()
print("Option 1 Total Bonus Payout: $", total_option_1)
This produces the following output:

This function checks four different circumstances using if-else statements, and when all four are met, it assigns a flat bonus.
Question 2: How much would the total bonus payout be with Option 2?
Technique: match-case
We will evaluate each driver’s eligibility using match-case and return a per-trip bonus only when conditions are met. Here is the code.
def option_2_bonus(row):
match (
row['trips_completed'] >= 12,
row['rating'] >= 4.7
):
case (True, True):
return row['trips_completed'] * 4
case _:
return 0
df['bonus_option_2'] = df.apply(option_2_bonus, axis=1)
total_option_2 = df['bonus_option_2'].sum()
print("Option 2 Total Bonus Payout: $", total_option_2)
Here is the output.

This function checks both requirements using match-case. It multiplies the number of completed trips by $4 if both are true. It returns zero otherwise.
Question 3: How many drivers would qualify for a bonus under Option 1 but not under Option 2?
Technique: Dictionary Mapping
After defining a dictionary that associates option names with their qualifying rules, we will use that dictionary to filter the data.
bonus_conditions = {
"option_1": (
(df['supply_hours'] >= 8) &
(df['accept_rate'] >= 0.9) &
(df['trips_completed'] >= 10) &
(df['rating'] >= 4.7)
),
"option_2": (
(df['trips_completed'] >= 12) &
(df['rating'] >= 4.7)
)
}
only_option_1 = bonus_conditions["option_1"] & (~bonus_conditions["option_2"])
count_only_option_1 = only_option_1.sum()
print("Drivers who qualify for Option 1 but not Option 2:", count_only_option_1)
Here is the output.

This logic filters drivers according to their qualification status after labeling and managing conditions using dictionary mapping.
Question 4: What percentages of drivers online completed less than 10 trips, had an acceptance rate of less than 90%, and had a rating of 4.7 or higher?
Technique: Classes and Polymorphism (OOP Style)
We'll create a class with a function that returns a percentage of drivers that satisfy all three requirements at once. This is the code.
class DriverFilters:
def __init__(self, dataframe):
self.df = dataframe
def all_conditions(self):
filtered = self.df[
(self.df['trips_completed'] < 10) &
(self.df['accept_rate'] < 0.9) &
(self.df['rating'] >= 4.7)
]
return (len(filtered) / len(self.df)) * 100
filters = DriverFilters(df)
qualified_pct = filters.all_conditions()
print(f"Percentage of drivers who meet all three conditions: {qualified_pct:.1f}%")
Here is the output.

This solution returns the accurate proportion of qualified drivers by simultaneously checking all three conditions inside a class method.
Performance Comparison of Case Handling Techniques
To deal with branching logic, we used four different approaches. Depending on the situation's complexity, data volume, and context, each has advantages.

Final Thoughts
We’ve walked through different ways to handle case statements in Python, from the classic if-elif-else chains to the newer match-case syntax, as well as dictionary mappings and object-oriented approaches. Each method has its own strengths, and the right choice really depends on the problem you’re trying to solve.
Using the Uber data project as an example showed how flexible Python can be when applying these techniques to real-world scenarios. Whether you prefer something quick and simple or a more structured, scalable approach, Python gives you plenty of options to keep your code clean and easy to follow.
If you’d like to sharpen your skills even further, try experimenting with these methods on your own projects. The more you practice, the more natural it becomes to choose the right tool for the job.
Share