More efficient/elegant branching

Chris Angelico rosuav at gmail.com
Mon Dec 9 06:46:58 EST 2019


On Mon, Dec 9, 2019 at 10:36 PM Musbur <musbur at posteo.org> 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

If the branches are completely independent, there's not really a lot
you can do differently. I'd rewrite these as return statements rather
than assigning to a variable and returning it at the end (which also
allows you to make them 'if' rather than 'elif'), but that's a
marginal gain. This is the sort of thing that tends to fall into the
category of "inherent complexity" - the code is complex because the
problem it's solving is complex. Imagine trying to write a function
that tells you whether to hold or tap a button:

def button_action(color, word):
    if color == "blue" and word == "Abort":
        return "Hold"
    if battery_count() > 1 and word == "Detonate":
        return "Tap"
    if color == "white" and "CAR" in indicators:
        return "Hold"
    if battery_count() > 2 and "FRK" in indicators:
        return "Tap"
    if color == "yellow":
        return "Hold"
    if color == "red" and word == "Hold":
        return "Tap"
    return "Hold"

You might be able to simplify this very slightly, but the conditions
are sufficiently varied that you can't really gain much, and they are
strictly ordered. The code here has as much complexity as the problem
it's solving, so you may as well just silence your linter's warnings
and carry on.

And yes, this sort of thing happens ALL THE TIME in real-world code.

https://thedailywtf.com/articles/The-Mythical-Business-Layer

IMO your code's fine. :)

ChrisA


More information about the Python-list mailing list