Use Python to do Switch Case

The switch statement can be very useful sometimes, and it is pretty easy to handle multiple conditions instead of writing a lot of if else. Here is the example of writing switch statement in most high-level programming languages:

switch ( a ) {
    case b:
        // Code
        break;
    case c:
        // Code
        break;
    default:
        // Code
        break;
}

But the problem is, Python doesn’t have switch statement.

There’s a proposal for that; however the status of this proposal is rejected. The explanation from python.org is you can simply use if...elif...else to do the same thing, and they don’t have consensus(yet) for adding switch into Python. You can check Python FAQ or PEP 275 to get more detail about the switch statement in Python.

Of course we know that we can always use if...elif...else to do the exactly the same thing, but if there are too many elif, that might cause some problem for people to understand the code.

They might not agree with me, but I do have a suck example to show the worst case of using if...elif...else. This was a part of code of parsing excel data.

for col in range(xls_data.ncols):
    if col == 5:
        row[0] = val;
    elif col == 3:
        row[1] = val;
    elif col == 4:
        row[2] = val;
    elif col == 6:
        if val != '':
            row[3] = val;
    elif col == 7:
        if val != '':
            row[4] = row[4] + val + ' ';
    elif col == 8:
        if val == 'yes' :
            row[4] = row[4] + 'att ';
    elif col == 9:
        if val == 'yes' :
            row[4] = row[4] + 'bt ';
    elif col == 10:
        if val == 'yes' :
            row[4] = row[4] + 'frontier ';
    elif col == 11:
        if val == 'yes' :
            row[4] = row[4] + 'mts ';
    elif col == 12:
        if val == 'yes' :
            row[4] = row[4] + 'nokia ';
    elif col == 13:
        if val == 'yes' :
            row[4] = row[4] + 'rogers ';
    elif col == 14:
        if val == 'yes' :
            row[4] = row[4] + 'sky ';
    elif col == 15:
        if val == 'yes' :
            row[4] = row[4] + 'tnz ';
    elif col == 16:
        if val == 'yes' :
            row[4] = row[4] + 'verizon ';
    elif col == 18:
        if val != 'N/A':
            row[6] = val;
    else:
        continue;

Using if...elif...else is definitely simple enough to write, but when you go back to check this long statement again, you might need couple minutes to understand what’s going on in here. Maybe it’s just me, but I personally don’t like to see a lot of if in the code.

I know that we don’t have switch statement in Python, but you can still use dictionary to make it look better than if...elif...else.

After I modified the whole if...elif...else statement, it looks much better to me.

def setRowData(idx, data):
    // do somthing

def getCobrandValue(idx, data):
    // generate sponsor information in here

cases = {
    3:  lambda data: setRowData(1, data),
    4:  lambda data: setRowData(2, data),
    5:  lambda data: setRowData(0, data),
    6:  lambda data: setRowData(3, data),
    7:  lambda data: setRowData(4, getCobrandValue(7,  data[4]), data),
    8:  lambda data: setRowData(4, getCobrandValue(8,  data[4]), data),
    9:  lambda data: setRowData(4, getCobrandValue(9,  data[4]), data),
    10: lambda data: setRowData(4, getCobrandValue(10, data[4]), data),
    11: lambda data: setRowData(4, getCobrandValue(11, data[4]), data),
    12: lambda data: setRowData(4, getCobrandValue(12, data[4]), data),
    13: lambda data: setRowData(4, getCobrandValue(13, data[4]), data),
    14: lambda data: setRowData(4, getCobrandValue(14, data[4]), data),
    15: lambda data: setRowData(4, getCobrandValue(15, data[4]), data),
    16: lambda data: setRowData(4, getCobrandValue(16, data[4]), data),
    18: lambda data: setRowData(5, data)
}

for col in range(xls_data.ncols):
    cases[col](row_data)

This is a complex example of doing switch in Python, which might be a little bit difficult to understand. Let’s start with some simple examples.

genders = {
    0: 'Female',
    1: 'Male'
}

gender = raw_input('Please select your gender: [0]Female [1]Male ')
output = 'Your gender is ' + genders[gender]
print(output)

So, what if I want to provide a default value for the gender information? You can use the dictionary’s .get() method to provide the default value for that.

genders = {
    0: 'Female',
    1: 'Male'
}

gender = raw_input('Please select your gender: [0]Female [1]Male ')
output = 'Your gender is ' + genders.get(gender, 'a secret~~')
print(output)

Sometimes, we need to have something more than just returning string, so let’s see how to pass parameter into the dictionary.

genders = {
    0: lambda age: 'girl' if age < 15 else 'lady',
    1: lambda age: 'boy' if age < 15 else 'gentlemen'
}

gender = input('Please select your gender: [0]Female [1]Male ')
age = input('Please provide your age: ')
output = 'Hello, ' + genders[gender](age) + '!'
print(output)

genders = {
    0: lambda age: 'girl' if age < 15 else 'lady',
    1: lambda age: 'boy' if age < 15 else 'gentlemen'
}

gender = input('Please select your gender: [0]Female [1]Male ')
age = input('Please provide your age: ')
output = 'Hello, ' + genders[gender](age) + '!'
print(output)

What if I also want to provide default case to avoid the KeyError issue in this situation?

genders = {
    0: lambda age: 'girl' if age < 15 else 'lady',
    1: lambda age: 'boy' if age < 15 else 'gentlemen'
}

gender = input('Please select your gender: [0]Female [1]Male ')
age = input('Please provide your age: ')
output = 'Hello, ' + genders.get(gender, lambda age: 'stranger')(age) + '!'
print(output)

If you need more functionalities, you can call function in lambda, or just call the function directly.

genders = {
    0: lambda age: parseAge(age) * 2,
    1: parseAge(age)
}

Like we mentioned before, you can always use if...elif...else to do the same thing, but here’s another way to make your code easier to understand and maintain.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s