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

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 I agree with Chris that this is the way to go. pylint be damned ;) > > def branch2(a, b, z): > """Elegant but inefficient because all expressions > are pre-computed althogh the first one is most likely > to hit""" Also, it doesn't work in the general case, like decision = [ (a == 0, "first"), (b/a > 1, "second"), ... > 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 You can shave off most of the overhead by precompiling the expressions: DECISIONS = [ ("a > 4 and b == 0", "first"), ("len(z) < 2", "second"), ("b + a == 10", "third") ] DECISIONS4 = [ (compile(expr, "<nofile>", "eval"), result) for expr, result in DECISIONS ] def branch4(a, b, z): for test, result in DECISIONS4: if eval(test): return result raise ValueError Using lambdas instead of precompiled expressions is a tad faster: DECISIONS5 = [ (eval("lambda a, b, z: " + expr), result) for expr, result in DECISIONS ] def branch5(a, b, z): for test, result in DECISIONS5: if test(a, b, z): return result raise ValueError This is is a slippery slope as you might now consider building branch1() from the DECISIONS list...

- Prev by Date:
**More efficient/elegant branching** - Next by Date:
**Regarding problem in python 3.8.0 installation** - Previous by thread:
**More efficient/elegant branching** - Next by thread:
**More efficient/elegant branching** - Index(es):