osdir.com


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

More efficient/elegant branching


On 9/12/19 12:27, Musbur wrote:
> Hello,
>
> I have a function with a long if/elif chain that sets a couple of
> variables according to a bunch of test expressions, similar to
> function branch1() below. I never liked that approach much because it
> is clumsy and repetetive, and pylint thinks so as well. I've come up
> with two alternatives which I believe are less efficient due to the
> reasons given in the respective docstrings. Does anybody have a better
> idea?
>
> def branch1(a, b, z):
> ??? """Inelegant, unwieldy, and pylint complains
> ??? about too many branches"""
> ??? if a > 4 and b == 0:
> ??????? result = "first"
> ??? elif len(z) < 2:
> ??????? result = "second"
> ??? elif b + a == 10:
> ??????? result = "third"
> ??? return result
>
> def branch2(a, b, z):
> ??? """Elegant but inefficient because all expressions
> ??? are pre-computed althogh the first one is most likely
> ??? to hit"""
> ??? decision = [
> ??????? (a > 4 and b == 0, "first"),
> ??????? (len(z) < 2,?????? "second"),
> ??????? (b + a == 10,????? "third")]
> ??? for (test, result) in decision:
> ??????? if test: return result
>
> def branch3(a, b, z):
> ??? """Elegant but inefficient because expressions
> ??? need to be parsed each time"""
> ??? decision = [
> ??????? ("a > 4 and b == 0", "first"),
> ??????? ("len(z) < 2",?????? "second"),
> ??????? ("b + a == 10",????? "third")]
> ??? for (test, result) in decision:
> ??????? if eval(test): return result
> (env) [dh at deham01in015:~/python/rscl_fdc/devel]$
>
Well if you really want to go this route, you may consider the following:

def branch4(a, b, z):
    decision = [
        ((lambda: a > 4 and b == 0), "first"),
        ((lambda: len(z) < 2), "second"),
        ((lambda: b + a == 10), "third")]
    for test, result in decision:
        if test(): return result