# Working around a lack of 'goto' in python

Roy Smith roy at panix.com
Sat Mar 6 22:16:10 CET 2004

```In article <UBo2c.26879\$pg4.12221 at newssvr24.news.prodigy.com>,
"Brett" <abc at def.net> wrote:

> Two areas where I've found 'goto' two be useful in other languages are in
> (untested examples in C++)

Working around the lack of "goto" in a language is kind of like trying
to figure out how to swim without a piano strapped to your back.  There
are lots of ways to do it, and even the worst of them is better than the
alternative.

> (1) deeply nested loops
>
> for (k=0; k < 10; ++k)
> for (j=0; j < 10; ++j)
> for (i=0; i <10; ++i)
>     if (/* some test */) goto END;
>
> END: /* continue */;

I've found two general solutions to the breaking out of a deeply nested
loop.  One possibility is to factor the loop out into its own function,
and break out of it with a return:

def findTheHiddenThing ():
for k in range (10):
for j in range (10):
for i in range (10):
if f (i, j, k) == theThingWeWant:
return

Another is to use an exception:

try:
for k in range (10):
for j in range (10):
for i in range (10):
if f (i, j, k) == theThingWeWant:
raise WeFoundIt ("in the last place we looked")
except WeFoundIt:
whatever

Neither of these ideas are particularly Python specific.  The first
method works in pretty much any procedural language.  The second only
works in languages that support exceptions (in some languages, exception
processing is fairly expensive, so it may not be universally acceptable).

Assuming both methods are equally feasable in your environment, the
choice of which to use may be driven by style, or one may just be a
better fit to your problem domain.

On the other hand, if you're doing linear searches of multi-dimensional
coordinate spaces, that may be a hint that you need to rethink how
you're solving the problem.  A different data structure may not only
eliminate the deeply nested loop, but could well be significantly faster
to execute.

> and (2) repeating a while or for loop from the beginning:
>
> BEGIN:
> for (n=0; n < 20; ++n)
>     if (/* some test */) goto BEGIN;

I'm going to go out on a limb on this one and say that if you need to
begin a loop from the beginning again, something is probably wrong with
how you're trying to solve the problem.  What you've really written is a
nested while/for loop.  In C, it should look something like this:

while (1)
for (n = 0; n < 20; ++n)
if (some test)
break

and now you're back to the same sort of "breaking out of a nested loop"
issue like you had above, with the same likely solutions.

```