views:

109

answers:

2

I have a very long conditional statement for deciding what action to take for a pair of variables a and b.

action = 0 if (a==0) else 1 if (a>1 and b==1) else 2 if (a==1 and b>1) else 3 if (a>1 and b>1) else -1

While it is nice with the compactness (in lines;) ) of this statement, it must exist a more elegant way to do this?

+9  A: 
if a==0:
   action = 0
elif a>1 and b==1:
   action = 1
elif a==1 and b>1:
   action = 2
elif a>1 and b>1:
   action = 3
else:
   action = -1

From the Zen of Python (excerpts):

Simple is better than complex.
Flat is better than nested.
Readability counts.
Tim Pietzcker
Parentheses are also unnecessary.
AndiDog
@AndiDog: Thanks, I hadn't even looked at them :)
Tim Pietzcker
This form also makes it much easier to see that the `(a==1 and b==1)` case has been omitted.
Paul McGuire
@Tim Very intressting. This is what my code looked like before I started fiddeling with it and ended up with the super long statement =) @Andi Parentheses where to make it more readable. @Paul (a==1 and b==1) has been intetionally omitted - it is covered by else -1, good point though, it is not readily apparent.
Theodor
@Theodor: There you have it: Python makes it natural to write good code. If you need to add something to make it more readable (like the parentheses in your "ternary operator cascade"), you probably need to rethink what you're doing :)
Tim Pietzcker
+2  A: 

If a and b both have known, small, integer ranges, you could make a dict. Say they're both always 0,1, or 2:

actionTable = { (0,0): 0, (0,1): 0, (0,2): 0,
                (1,0):-1, (1,1):-1, (1,2): 2,
                (2,0):-1, (2,1): 1, (2,2): 3 }

return actionTable[ (a,b) ]

But this is a little bit opaque, unscalable, and hard to maintain. If the action table is big and complex and able to be generated programmatically, though, it's a useful technique for the toolbox.

Russell Borogove
I like the look up table idea, however, a and b can (in theory) take arbitrary large values. I'll keep it in memory though.
Theodor