Search code examples
pythonreturnconditional-operator

Why can't I use return() in a conditional for flow control in Python?


Consider this function:

def parity(num):
    num % 2 == 0 and return "that is even"
    return "that is odd"

The first line of the function is a syntax error (I'm using v 3.7.3). Why? Seems like you should be able to "return" from wherever you want to.

NOTE: I realize that in this specific case I could use

return "that is even" if num % 0 == 0 else "that is odd"

That's not my issue. My issue is that it's much more compact, and easier to read the flow, if you write:

condition 1 or return "condition one was not met"
condition 2 or return "condition two was not met"
condition 3 or return "contition three what not met"
[rest of the function goes here]

than:

   if not condition 1:
        return "condition one was not met"
   if not condition 2:
        return "condition two was not met"
   if not condition 3:
        return "condition three was not met"
   [rest of the function goes here]

and--apart from this preference for brevity/readability--it simply doesn't make sense to me that I can't just execute a return in that place in the code. The documentation for return says:

7.6. The return statement

return_stmt ::=  "return" [expression_list]

return may only occur syntactically nested in a function definition, not within a nested class definition.

If an expression list is present, it is evaluated, else None is substituted.

return leaves the current function call with the expression list (or None) as return value.

When return passes control out of a try statement with a finally clause, that finally clause is executed before really leaving the function.

In a generator function, the return statement indicates that the generator is done and will cause StopIteration to be raised. The returned value (if any) is used as an argument to construct StopIteration and becomes the StopIteration.value attribute.

In an asynchronous generator function, an empty return statement indicates that the asynchronous generator is done and will cause StopAsyncIteration to be raised. A non-empty return statement is a syntax error in an asynchronous generator function.

It doesn't look to me like anything in that definition precludes the usage I'm attempting. Is there something here that I'm not understanding?


Solution

  • The reason is right in its name. It’s a statement. Statements are different things than expressions. You can compose several expressions into a larger expression. Not so with statements; the defining characteristic of a statement is that it cannot be part of a larger expression, partly because it behaves differently (usually controls flow), and partly because it doesn’t result in a value which could be composed into a larger expression.