Looking for a slick way to classify relationship between two numbers, without tons of if/else

Dave Angel davea at ieee.org
Mon Jul 6 23:28:39 EDT 2009


palewire wrote:
> In my application, I'd like to have a function that compares two values,
> either of which may be null, and then classify the result depending on
> whether one is higher or lower than the other.
>
> I find myself writing something clunky like this, and I'm curious whether
> anyone might know a more elegant way for parsing this out.
>
> def compare(a, b):
>     if not a and not b:
>         return "No data"
>     else:
>         if a == 0 and b == 0:
>             return "Never had"
>         else:
>             if a == b:
>                 return "Stayed the same"
>             elif a < b:
>                 return "Gained"
>             elif a > b and b > 0:
>                 return "Lost Some"
>             elif a > b and b == 0:
>                 return "Lost All"
>
> If there's some obvious way to search for this solution online, feel free to
> slap me with that. I tried digging around on Google and couldn't come up
> with much.
>
> Thanks much.
>   
Before one can "optimize" a function, one needs to get the function 
correct.  Looks to me that if a and b are both zero, it'll say "No data" 
and never get to the "Never had" test.  And if a is positive and b is 
None, it'll return None, rather than any string.

Anyway, any "optimized" construct is going to be nearly as big as this.  
You'd have to define a list of strings, and then compute an index value 
that gave you the appropriate value.  While I could probably come up 
with such, I hardly think it's worthwhile.  The cases are confusing 
enough to me that I'd not want to make the code any less readable by 
some formula & lookup.

That brings us to the question of what is more elegant.  To me the 
elegant code is readable first, and efficient (space & time) second.  I 
suspect efficiency would be nearly optimal by careful ordering of the 
nested ifs.  Find the most likely cases, and test for them first.

If this is a programming puzzle, for entertainment purposes, here's the 
way I'd tackle making it "efficient" obfuscated code.  Start by checking 
if either value is None.  Something like:

table = ("Lost Some","Lost All","Gained","Gained","Stayed the 
same","Never had, never will")
def compare2(a,b):
    global table
    if a is None or b is None:
        return "Invalid data"
    return table[4*(a==b)+2*(a<b)+(b==0)]

davea



More information about the Python-list mailing list