Avoiding “break” and “continue” statements in Python

Manel Vilar
2 min readMay 17, 2020

When you are coding, is not very infrequent that you find pieces of code like this (alert, pseudo-code) when traversing a loop:

for foo in list:
if foo > bar:
continue
do_something(foo)

Or even something more convolute:

new_list = []for foo in list:
if foo > bar:
new _list.append("...")
break
if not new_list:
do_something(...)

You can improve it a bit adding a very convenient else condition at the end of the for loop, as I was pointed out by a reader, but what I am interested in is in removing the break statement inside it.

As you see, things can get complex easily, while readability degrades quickly. For some authors, both break and continue are nothing more that renamed GOTO statements, that are considered harmful since very long time ago, as they jump into the code breaking the loop logic. You can always test your methods, but there are some other ways of simplifying these kind of constructions.

For the first case, an easy way would be to use a list comprehension:

[do_something(foo) for foo in list if foo > bar]

Or a filter with a lambda, a short form for nameless functions:

filter(list, lambda value: foo > bar)

That’s pretty much trivial, but, what about the second case? We want the loop to stop executing when the first occurrence appears, so we cannot use a comprehension. Then we can use an exception in combination with an iterator. Something like this:

try:
next((value for value in list if value > some))
except StopIteration:
do_something(...)

Instead of a list comprehension, that uses squared brackets, [], we make a generator using parenthesis, (). That allows us to user the language built-in helpers next and iter. The first one will stop at first occurrence, while the second will return the current value when it exists. When there are no values, it will throw an exception, that we can use for our purpose. Be careful of not adding the condition before the ‘for’ keyword, otherwise it will not work, as the iterator will always be evaluated.

I was quite reticent about the use of exceptions for program logic instead of confining them to error management, but in after I few years in Python, I got used to them and find them more readable than more convencional constructions, like for and while loops. Especially when used in combination with high level tools like generators, like in this case.

Notice that some functional libraries add the convenience method first(), but that only gets the first successful from a collection or iterable, it doesn’t stop executing it.

Python and their developers have their own way of doing things, so maybe you have a different point of view. In any case, that’s an option that you can use. And the more (options), the merrier.

--

--

Manel Vilar

Web developer focused on Javascript, PHP, Python and more...