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.



More information about the Python-list mailing list