Thursday, May 28, 2009

switch statements in python

I may as well weight in on the absence of a switch statement in Python, though the topic has been addressed, see:

Python Zone » Python switch statement, or
http://dinomite.net/2008/python-switch-statements-part-2

Here are some examples of switching structures using dictionaries:

# switch example 1
cases = {
'a':
    lambda: 'one',
'b':
    lambda: 'two',
'default':
    lambda: 'three'
}

switch = lambda c: cases.get(c, cases['default'])()

var = ['b','xxx']
for v in var:
    out = switch(v)
    print("Switch on %s = %s"%(v,out))


# switch example 2
op = raw_input("Enter operation for 2 'op' 3: ")

if op in "+-*/":
    print("2 %s 3 = " % op)
else:
    print("'%s' is an unkown operation." % op)

cases = {
     '+': lambda : 2 + 3,
     '-': lambda : 2 - 3,
     '*': lambda : 2 * 3,
     '/': lambda : 2. / 3.
     }

switch = cases.get(op, lambda : 0)()

print(switch)


# switch example 3
name = raw_input("What is your name? ")
op = raw_input("enter 'l' or 'p'")

cases = {
    'l': len,
    'p': lambda txt: txt.upper()
    }

def default(obj):
    print("Invalid entry, %s" % obj)

switch = cases.get(op, default)
out = switch(name)

print(out)
I would say that each of these is as readable as C's switch statement.  I can't say anything for performance, since I haven't run any tests--but Python's dictionaries are fast.   In fact, if I understand the implementation correctly this pattern is pretty much what the switch statement does--set up a hash table (i.e. a dictionary) of test values and choose a code block based on the condition entered.  

The main argument would be the cumbersomeness of switch on larger blocks of code.  To do that you need to move each block of switch code into a function defined by def.   My only response to that is that if you're writing large blocks of code inside a switch statement, you should think about putting it in a function--in my experience there is usually a fair amount of reused code inside a large switch statement, since the conditions usually each deal with a separate state of a single variable.  Also, the difference in readability between switch and nested if...then..else's diminishes rapidly the larger the conditional code blocks get.

So, should Python have a switch statement?  Readability of code long term may benefit if there is one way to do a switch as opposed to using different, although similar patterns like above.  But in general, I support keeping control flow logic made of the simplest building blocks--in the long run I think that keeps bloat down and enforces more thinking about the nature of the specific programming problem at hand.

But if a switch statement was added to Python, I'd probably use it.





No comments:

Post a Comment