# Avoid extra line for return

**URL:** <https://discuss.python.org/t/avoid-extra-line-for-return/18960>\
**Category:** Python Help\
**Created:** [September 11, 2022, 5:32pm UTC](https://discuss.python.org/t/avoid-extra-line-for-return/18960 "2022-09-11T17:32:54Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![vainaixr](https://avatars.discourse-cdn.com/v4/letter/v/5f8ce5/32.png) [@vainaixr](https://discuss.python.org/u/vainaixr)\
**Post date:** [September 11, 2022, 5:32pm UTC](https://discuss.python.org/t/avoid-extra-line-for-return/18960/1 "2022-09-11T17:32:55Z")

</div>

I am seeing this kind of pattern again and again which always uses one additional line for `return`

```auto
def func1(x):
  if x > 1:
    return
  print(x)
  ...
  (rest of function)
  ...

```

```auto
def func2(y):
  if len(y) < 2:
    return
  print(y)
  ...
  (rest of function)
  ...

```

could I achieve the same in one line?

1. gives error

```auto
def func(x):
  return None if x > 1
  print(x)

```

1. works, but after the return line the function is not executed

```auto
def f():
  return None if 1 == 2 else print(10)
  print(20)

```

→

```auto
10

```

(20 did not get printed, the execution ended on the return line)

I would want something like,

```auto
def func(x):
  return None if x > 1 else [someway to continue in the function]

```

---

<div class="post-metadata">

**Author:** ![barry-scott](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@barry-scott](https://discuss.python.org/u/barry-scott)\
**Post date:** [September 11, 2022, 5:43pm UTC](https://discuss.python.org/t/avoid-extra-line-for-return/18960/2 "2022-09-11T17:43:50Z")

</div>

You can put the return after the : of the if.  
Personally I like the use of a separate line as I find it easier to read.

---

<div class="post-metadata">

**Author:** ![vainaixr](https://avatars.discourse-cdn.com/v4/letter/v/5f8ce5/32.png) [@vainaixr](https://discuss.python.org/u/vainaixr)\
**Post date:** [September 11, 2022, 5:54pm UTC](https://discuss.python.org/t/avoid-extra-line-for-return/18960/3 "2022-09-11T17:54:27Z")

</div>

that leads to pylint issue

```auto
C0321: More than one statement on a single line (multiple-statements)

```

would not like pylint issues

---

<div class="post-metadata">

**Author:** ![barry-scott](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@barry-scott](https://discuss.python.org/u/barry-scott)\
**Post date:** [September 11, 2022, 5:58pm UTC](https://discuss.python.org/t/avoid-extra-line-for-return/18960/4 "2022-09-11T17:58:13Z")

</div>

And that would make Barry happy that pylint prefers the two line version 😄

---

<div class="post-metadata">

**Author:** ![vainaixr](https://avatars.discourse-cdn.com/v4/letter/v/5f8ce5/32.png) [@vainaixr](https://discuss.python.org/u/vainaixr)\
**Post date:** [September 11, 2022, 6:06pm UTC](https://discuss.python.org/t/avoid-extra-line-for-return/18960/5 "2022-09-11T18:06:08Z")

</div>

I have a twenty-line function, and four of those lines are these `return` statements.  
I think so there should be a way to avoid lines which have only `return` written in them.

---

<div class="post-metadata">

**Author:** ![gkb](https://avatars.discourse-cdn.com/v4/letter/g/6f9a4e/32.png) [@gkb](https://discuss.python.org/u/gkb)\
**Post date:** [September 11, 2022, 6:29pm UTC](https://discuss.python.org/t/avoid-extra-line-for-return/18960/6 "2022-09-11T18:29:46Z")

</div>

It looks to me like you want a way to specify preconditions which must be fulfilled before your function is executed. One way to achieve this is with a decorator:

```python
from functools import wraps
from typing import Callable, List

def check_preconditions(preconditions: List[Callable]):
    def decorator(f: Callable):
        @wraps(f)
        def f_new(*args, **kwargs):
            for precond in preconditions:
                if not precond(*args, **kwargs):
                    return
            return f(*args, **kwargs)

        return f_new

    return decorator

```

You would then use it like this:

```python
@check_preconditions([lambda x: x > 1, lambda x: x < 3])
def f(x):
    return x

print(f(0))
print(f(1))
print(f(2))
print(f(3))

# prints None, None, 2, None

```

But I admit it is probably overkill if you only need these checks four times in a single function.

---

<div class="post-metadata">

**Author:** ![steven.daprano](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/steven.daprano/32/1083_2.png) [@steven.daprano](https://discuss.python.org/u/steven.daprano)\
**Post date:** [September 11, 2022, 6:37pm UTC](https://discuss.python.org/t/avoid-extra-line-for-return/18960/7 "2022-09-11T18:37:42Z")

</div>

How is the interpreter supposed to know to return early from the function, if you don’t include a return statement?

If you really, really don’t want the return statement on its own line, you can include it after the colon: `if condition: return`.

If the linter complains, that’s a sign that most people think that what you are doing is bad style. Either obey the linter, or disable that check.

---

<div class="post-metadata">

**Author:** ![Rosuav](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/rosuav/32/3429_2.png) [@Rosuav](https://discuss.python.org/u/Rosuav)\
**Post date:** [September 11, 2022, 6:38pm UTC](https://discuss.python.org/t/avoid-extra-line-for-return/18960/8 "2022-09-11T18:38:46Z")

</div>

> [@vainaixr](#):
>
> that leads to pylint issue
> 
> ```auto
> C0321: More than one statement on a single line (multiple-statements)
> 
> ```
> 
> would not like pylint issues

Disable the pylint complaint, and your problem vanishes.

---

<div class="post-metadata">

**Author:** ![vainaixr](https://avatars.discourse-cdn.com/v4/letter/v/5f8ce5/32.png) [@vainaixr](https://discuss.python.org/u/vainaixr)\
**Post date:** [September 11, 2022, 6:43pm UTC](https://discuss.python.org/t/avoid-extra-line-for-return/18960/9 "2022-09-11T18:43:56Z")

</div>

this thing could work for some function, but in the function I use, none of those four are preconditions, the variables are evaluated in the function, and then I write a `if` statement, and then `return` if it satisifies.

---

<div class="post-metadata">

**Author:** ![vainaixr](https://avatars.discourse-cdn.com/v4/letter/v/5f8ce5/32.png) [@vainaixr](https://discuss.python.org/u/vainaixr)\
**Post date:** [September 11, 2022, 6:45pm UTC](https://discuss.python.org/t/avoid-extra-line-for-return/18960/10 "2022-09-11T18:45:55Z")

</div>

it appears to be a problem with how `return` works in the background, maybe it is similar to how `break`, `continue` work, therefore, cannot execute lines after it.

plus I want the `return` to be avoided, that is,

```auto
def func(x):
  return None if x > 1 else [someway to continue in the function]
  ...
  (rest of function)
  ...

```

there should be a way to not execute the return despite using `return` as the first word in a line

something like a `avoid` keyword, which works like,

```auto
def f(x):
  return 1 if x > 1 else avoid
  ...
  (continues execution of rest of the function if the condition is not met)
  ...

```

or similar for `break`, `continue` also,

```auto
for i in [1, 2, 3]:
  break if i == 2 else avoid
  ...
  (for i = 1, would execute the entire for loop, would break out \
   of the for loop when i = 2, thus, i = 3 never happens)
  ...

```

```auto
for i in [1, 2, 3]:
  continue if i == 2 else avoid
  ...
  (for i = 1, and i = 3, would execute the entire for loop)
  ...

```

---

<div class="post-metadata">

**Author:** ![vovavili](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/vovavili/32/38249_2.png) [@vovavili](https://discuss.python.org/u/vovavili)\
**Post date:** [September 11, 2022, 7:44pm UTC](https://discuss.python.org/t/avoid-extra-line-for-return/18960/11 "2022-09-11T19:44:57Z")

</div>

Just configure your .pylintrc file to ignore PEP8 E701 if it irks you and you’re good. Situations like these are what you get in a language that doesn’t have curly braces and semicolons but that’s pretty much a deliberate design choice.

---

<div class="post-metadata">

**Author:** ![cameron](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/cameron/32/2658_2.png) [@cameron](https://discuss.python.org/u/cameron)\
**Post date:** [September 11, 2022, 9:51pm UTC](https://discuss.python.org/t/avoid-extra-line-for-return/18960/12 "2022-09-11T21:51:05Z")

</div>

By via Discussions on [Python.org](http://Python.org) at 11Sep2022 18:56:

> it appears to be a problem with how `return` works in the background,  
> maybe it is similar to how `break`, `continue` work, therefore, cannot  
> execute lines after it.

Well, it _is_ control flow. That’s what `return` _does_!

> plus I want the `return` to be avoided, that is,
> 
> ```auto
> def func(x):
> return None if x > 1 else [someway to continue in the function]
> ...
> (rest of function)
> ...
> 
> ```
> 
> there should be a way to avoid the return despite using `return` as the first word in a line

People have mentioned the:

```
 if condition: return

```

form, and that you can tell pylint to not complaint about that.

You can also go:

```
 def func(x):
     if condition:
         the rest of the function

```

so that “not condition” skips that stuff and uses the end-of-function  
return. Returning in the middle, as you are doing, is called “early  
return”, and sometimes discouraged because the flow to the function  
result is more obscure. The tradeoff to that can be more control flow  
indentation such as the if-statement above.

Remember that a lot of lint checks are style checks, and can be tuned  
either to prefer some style or simply disabled. Other checks are more  
semantic such as an undefine or set-and-unused variable.

Cheers,  
Cameron Simpson [cs@cskk.id.au](mailto:cs@cskk.id.au)

---

<div class="post-metadata">

**Author:** ![steven.daprano](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/steven.daprano/32/1083_2.png) [@steven.daprano](https://discuss.python.org/u/steven.daprano)\
**Post date:** [September 12, 2022, 2:05am UTC](https://discuss.python.org/t/avoid-extra-line-for-return/18960/13 "2022-09-12T02:05:29Z")

</div>

> [@](#):
>
> there should be a way to avoid the return despite using `return` as the first word in a line

No there shouldn’t.

---

<div class="post-metadata">

**Author:** ![ReverendJim](https://avatars.discourse-cdn.com/v4/letter/r/ee59a6/32.png) [@ReverendJim](https://discuss.python.org/u/ReverendJim)\
**Post date:** [September 13, 2022, 5:36pm UTC](https://discuss.python.org/t/avoid-extra-line-for-return/18960/14 "2022-09-13T17:36:56Z")

</div>

RE: Adding decorators @MyFullName

Overkill, indeed. You’ve taken what was a simple piece of code and made it (without a lot of effort) unreadable.

---

<div class="post-metadata">

**Author:** ![ChrisBarker-NOAA](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/chrisbarker-noaa/32/17339_2.png) [@ChrisBarker-NOAA](https://discuss.python.org/u/ChrisBarker-NOAA)\
**Post date:** [September 14, 2022, 2:01am UTC](https://discuss.python.org/t/avoid-extra-line-for-return/18960/15 "2022-09-14T02:01:00Z")

</div>

I think yo are a bit confused about expressions vs statements:

an expression evaluates to a value, e.g.:

`x + 5`

a statement does something, e.g.

`return this’

as you see, return is a staemetn, tis returns from the funtion, returning the value after it.

finally, a “ternary expression”:

`x if this else that`

is an expression – it evaluates to a value – in this case, either the value of `x` or `that`, depending on the truthiness of `this`.

So:

When you write:

`return None if x \> 1 else something\_else

you are writing:

“terminate the function and return the value that the follwoing expressin evaluates to” – the following expression being:

`None if x > 1 else something_else`

so the function will alway end here, and return either None or somthing\_else.

I think the confusion is that:

`if this:`

is a statement, whereas:

x if this else that

while using the “if” in a similar way, is an expressions.

Anyway, you haven’t posted the full twenty line, function, so hard to tell if it can be clearnly refa tors, but:

```auto
if condition1:
    return this
if condition2:
    return that
some_more
lines_of_code

```

is fine – no reason to remove lines of code just for brevity.

On the other hand, some folks think returning in the middle of a function can be bad style – it’s a bit harder to see at a glance where the function ends, so you can do:

```auto
if something:
   return_value = this
elif somethign_else:
    return_value = that
else:
    a_bunch
    more_code
...
return return_value

```

That way there is a dingle return, at the end of the function.

HTH,

-CHB

---

<div class="post-metadata">

**Author:** ![kenahoo](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/kenahoo/32/5714_2.png) [@kenahoo](https://discuss.python.org/u/kenahoo)\
**Post date:** [September 18, 2022, 11:08pm UTC](https://discuss.python.org/t/avoid-extra-line-for-return/18960/16 "2022-09-18T23:08:34Z")

</div>

@vainaixr - Just to provide a little bit of context: Perl has exactly this syntax, and has had it since at least 1994 when Perl 5 was released (Perl 4 may also have had it, I can’t remember). It’s called a “statement modifier”: [perlsyn - Perl syntax - Perldoc Browser](https://perldoc.perl.org/perlsyn) . Your original example translates almost verbatim:

```auto
sub func {
  my ($x) = @_;
  return if $x > 1;
  print(x);
}

```

I’ve quite often wished for this syntax to be available in Python for exactly the reasons you gave in your first post. It’s perfect for highlighting the control flow, while allowing for brevity of expression.

As for whether it “looks natural” - I’d say it looks a lot more natural than the related Python construct `x = 3 if y > 5 else 6`, which is always jarring to me in the way it splits the two possible assignment expressions by putting the condition between them.

Anyway, just a point of history here.

---

<div class="post-metadata">

**Author:** ![steven.daprano](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/steven.daprano/32/1083_2.png) [@steven.daprano](https://discuss.python.org/u/steven.daprano)\
**Post date:** [September 19, 2022, 12:29am UTC](https://discuss.python.org/t/avoid-extra-line-for-return/18960/17 "2022-09-19T00:29:01Z")

</div>

Python is capable of the exact same “statement modifier”, with a slightly different syntax. You can even put it on one-line:

```auto
if x > 1: return

```

While Perl hides the control flow at the end of statement, it is actually Python which genuinely highlights it by putting it at the beginning of the line.

It is only a slight exaggeration to say that Perl’s philosophy is to never have one syntax for something when they can have five.

> [@](#):
>
> it looks a lot more natural than the related Python construct `x = 3 if y > 5 else 6`, which is always jarring to me

“What are you doing on the weekend?”

“I’m going to the zoo, if the weather is nice, otherwise I’m staying home to binge-watch David Attenborough documentaries.”

The Python ternary `if` operator is fine, it follows common English syntax.

---

<div class="post-metadata">

**Author:** ![Rosuav](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/rosuav/32/3429_2.png) [@Rosuav](https://discuss.python.org/u/Rosuav)\
**Post date:** [September 19, 2022, 3:17am UTC](https://discuss.python.org/t/avoid-extra-line-for-return/18960/18 "2022-09-19T03:17:44Z")

</div>

> [@steven.daprano](#):
>
> While Perl hides the control flow at the end of statement, it is actually Python which genuinely highlights it by putting it at the beginning of the line.

That’s most definitely false. I don’t personally like the Perl syntax, but it DOES put the truly important part at the start of the line: it is capable of halting the function’s execution. That is the true control flow. Calling the “if” statement the control flow is like saying that there’s a secret “goto” in there - that is to say, technically correct (probably) and utterly useless.

It’s a conditional return statement. There’s nothing inherently wrong with focusing on the return, rather than the if. It’s on par with the way that a list comprehension focuses on the value, even when there’s some filtering going on - `[x*3 for x in numbers if x % 2]`

But I still don’t like the Perl syntax and don’t see a lot of value in adding it to Python.

> [@](#):
>
> > [@](#):
> >
> > it looks a lot more natural than the related Python construct `x = 3 if y > 5 else 6`, which is always jarring to me
> 
> “What are you doing on the weekend?”
> 
> “I’m going to the zoo, if the weather is nice, otherwise I’m staying home to binge-watch David Attenborough documentaries.”
> 
> The Python ternary `if` operator is fine, it follows common English syntax.

English, even more than Perl, follows the philosophy of never having one syntax when it can have one from Greek, three from Latin, two from French, two from German (nearly identical to the Latin ones), and one that Shakespeare used a few times and became famous in quotes, even though nobody would use them outside of those specific lines.

(Only a slight exaggeration, and I’m not even sure of that.)

“What are you doing on the weekend?”

“If the weather is nice, I’ll go to the zoo, otherwise I’m staying home.”

At least as common as the syntax you describe.

“Go to the zoo or stay home, depending on whether the weather’s nice.”

Less common but viable.

---

<div class="post-metadata">

**Author:** ![kenahoo](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/kenahoo/32/5714_2.png) [@kenahoo](https://discuss.python.org/u/kenahoo)\
**Post date:** [September 19, 2022, 4:08am UTC](https://discuss.python.org/t/avoid-extra-line-for-return/18960/19 "2022-09-19T04:08:35Z")

</div>

> [@steven.daprano](#):
>
> Python is capable of the exact same “statement modifier”, with a slightly different syntax. You can even put it on one-line:
> 
> ```auto
> if x > 1: return
> 
> ```

That is not at all what a statement modifier means. You can find the definition in the link that I posted.

> [@steven.daprano](#):
>
> While Perl hides the control flow at the end of statement, it is actually Python which genuinely highlights it by putting it at the beginning of the line.

I was talking about the control flow of the `return`, which is vastly more important to notice than the `if` in this case.

> [@steven.daprano](#):
>
> It is only a slight exaggeration to say that Perl’s philosophy is to never have one syntax for something when they can have five.

Couldn’t resist a provincial jab? That’s neither true nor helpful to the discussion.

> [@steven.daprano](#):
>
> “I’m going to the zoo, if the weather is nice, otherwise I’m staying home to binge-watch David Attenborough documentaries.”
> 
> The Python ternary `if` operator is fine, it follows common English syntax.

This argument holds no water. English has dozens of constructions available for saying something like this. Python’s ternary `if` simply chooses one of those (not a particularly clear one, IMO).

Additionally, your David Attenborough example is incorrect, because Python doesn’t allow a full statement in its ternary `if` construction slots, just expressions. A corrected example (showing how awkward this actually is in English too) would be:

> “My activity this weekend will be going to the zoo, if the weather is nice, otherwise staying home to binge-watch David Attenborough documentaries.”

```auto
activity = zoo if weather == nice else attenborough

```

The fact that your English statement won’t actually translate directly into syntactically valid Python illustrates the point:

```auto
>>> activity = zoo if weather == nice else activity = attenborough
  File "<stdin>", line 1
    activity = zoo if weather == nice else activity = attenborough
               ^
SyntaxError: cannot assign to conditional expression

```

Finally - I’m not sure why you’re of the opinion that `x() if y` is so strange, but `w = x() if y else z()` is perfectly clear. It seems like you might just be used to what Python has decided to offer, so it feels natural after a while. To me, they seem like unnatural language choices.

---

<div class="post-metadata">

**Author:** ![Rosuav](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/rosuav/32/3429_2.png) [@Rosuav](https://discuss.python.org/u/Rosuav)\
**Post date:** [September 19, 2022, 4:38am UTC](https://discuss.python.org/t/avoid-extra-line-for-return/18960/20 "2022-09-19T04:38:27Z")

</div>

> [@kenahoo](#):
>
> Finally - I’m not sure why you’re of the opinion that `x() if y` is so strange, but `w = x() if y else z()` is perfectly clear. It seems like you might just be used to what Python has decided to offer, so it feels natural after a while. To me, they seem like unnatural language choices.

If by “unnatural language choices” you mean that the choices are made to suit the needs of a non-natural language, then yes, that’s exactly what they are 🙂 Natural languages like English follow completely different rules and often make different decisions. Python tries to be the best Python it can be, without worrying about whether it makes good English.

(That might seem patently obvious, but there was a movement in the 1960s-70s ish to have computer languages become more like human languages, which gave us a few utter abominations that died quiet deaths with no regrets, and a few survivors like SQL - which still make appallingly bad human languages. I mean, can you _imagine_ trying to hold a conversation with a human using nothing but SQL-legal syntax???)

[Next page](https://discuss.python.org/t/avoid-extra-line-for-return/18960.md?page=2)
