Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pythonic way to avoid "if x: return x" statements

People also ask

How do you not use if in python?

Using the 'if not' Python statement to check if it negates the output of an 'if' statement. As you can see, the code under the 'if' block was returned although the condition returned false.


Alternatively to Martijn's fine answer, you could chain or. This will return the first truthy value, or None if there's no truthy value:

def check_all_conditions():
    return check_size() or check_color() or check_tone() or check_flavor() or None

Demo:

>>> x = [] or 0 or {} or -1 or None
>>> x
-1
>>> x = [] or 0 or {} or '' or None
>>> x is None
True

You could use a loop:

conditions = (check_size, check_color, check_tone, check_flavor)
for condition in conditions:
    result = condition()
    if result:
        return result

This has the added advantage that you can now make the number of conditions variable.

You could use map() + filter() (the Python 3 versions, use the future_builtins versions in Python 2) to get the first such matching value:

try:
    # Python 2
    from future_builtins import map, filter
except ImportError:
    # Python 3
    pass

conditions = (check_size, check_color, check_tone, check_flavor)
return next(filter(None, map(lambda f: f(), conditions)), None)

but if this is more readable is debatable.

Another option is to use a generator expression:

conditions = (check_size, check_color, check_tone, check_flavor)
checks = (condition() for condition in conditions)
return next((check for check in checks if check), None)

Don't change it

There are other ways of doing this as the various other answers show. None are as clear as your original code.


In effectively the same answer as timgeb, but you could use parenthesis for nicer formatting:

def check_all_the_things():
    return (
        one()
        or two()
        or five()
        or three()
        or None
    )

According to Curly's law, you can make this code more readable by splitting two concerns:

  • What things do I check?
  • Has one thing returned true?

into two functions:

def all_conditions():
    yield check_size()
    yield check_color()
    yield check_tone()
    yield check_flavor()

def check_all_conditions():
    for condition in all_conditions():
        if condition:
            return condition
    return None

This avoids:

  • complicated logical structures
  • really long lines
  • repetition

...while preserving a linear, easy to read flow.

You can probably also come up with even better function names, according to your particular circumstance, which make it even more readable.