| Store | Cart

Working around a lack of 'goto' in python

From: Stephen Horne <ste...@ninereeds.fsnet.co.uk>
Mon, 08 Mar 2004 05:01:04 +0000
On Sat, 06 Mar 2004 16:16:10 -0500, Roy Smith <roy at panix.com> wrote:

>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.

:-)

>> (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:

<snip>

>Another is to use an exception:

Another occurred to me. Turn the three nested loops into one loop.

In C...

  i = j = k = 0;

  while (k < 10)
  {
    if (/* some test */)  break;

    i++; if (i == 10) { i = 0; j++; if (j == 10) { j = 0; k++; } }
  }

If it was needed a lot, I might try...

  /*  Cyclic increment

      Increment var reference by p and test against limit.
      if limit reached, reset to zero and return true
      to indicate overflow
  */
  int CInc (int *p, int p_Limit)
  {
    (*p)++;
    if (*p < p_Limit)  return 0;
    *p = 0;
    return true;
  }

  ...

  i = j = k = done = 0;

  while (!done)
  {
    if (/* some test */)  break;

    done = CInc (&i, 10) && CInc (&j, 10) && CInc (&k, 10);
  }

though I would at least try to think of a decent name for that
function.


This can just about be translated to Python...

  class cyclicint :
    def __init__ (self, p) :
      self.value = p

    def inc (self, p_Limit) :
      self.value++
      if self.value < p_Limit : return false
      self.value = 0
      return true

    def __int__ (self) :
      return value

  ...

  i = cyclicint (0); j = cyclicint (0); k = cyclicint (0); done = 0

  while not done :
    if some test :  break

    done = i.inc (10) and j.inc (10) and k.inc (10)


But really that's a bad idea - there's a much neater way...

  for (i,j,k) in [(x,y,z) for x in range(10)
                          for y in range(10)
                          for z in range(10) ] :
    if sometest : break


This should, of course, get a bit more efficient in Python 2.4 when we
get generator expressions :-)

I can also imagine a helper function...

  for (i,j,k) in cross(range(10), range(10), range(10)) :
    if sometest : break


-- 
Steve Horne

steve at ninereeds dot fsnet dot co dot uk

Recent Messages in this Thread
Brett Mar 06, 2004 06:18 pm
Andrew Koenig Mar 06, 2004 06:30 pm
Carmine Noviello Mar 06, 2004 06:41 pm
Jeff Schwaber Mar 06, 2004 06:41 pm
Peter Otten Mar 06, 2004 06:48 pm
Rene Pijlman Mar 06, 2004 06:49 pm
Christian Tismer Mar 06, 2004 08:50 pm
Roy Smith Mar 06, 2004 09:16 pm
Stephen Horne Mar 08, 2004 05:01 am
Dan Bishop Mar 06, 2004 11:23 pm
David M. Cooke Mar 07, 2004 08:49 am
Stephen Horne Mar 07, 2004 06:35 pm
Roy Smith Mar 07, 2004 06:54 pm
Stephen Horne Mar 07, 2004 07:57 pm
Roy Smith Mar 07, 2004 08:49 pm
Stephen Horne Mar 08, 2004 02:54 am
benjamin schollnick Mar 08, 2004 03:38 am
Stephen Horne Mar 08, 2004 05:10 am
Roger Binns Mar 07, 2004 10:33 pm
Roy Smith Mar 08, 2004 02:11 am
Roger Binns Mar 08, 2004 05:09 am
Georgy Mar 08, 2004 09:09 am
Jeff Epler Mar 08, 2004 02:50 pm
Mel Wilson Mar 08, 2004 03:43 pm
Roger Binns Mar 08, 2004 08:43 pm
Donn Cave Mar 08, 2004 10:46 pm
Roger Binns Mar 09, 2004 12:11 am
Stephen Horne Mar 08, 2004 03:30 am
Stephen Horne Mar 08, 2004 05:29 am
Y2KYZFR1 Mar 08, 2004 04:41 pm
Lou Pecora Mar 08, 2004 04:59 pm
Y2KYZFR1 Mar 09, 2004 04:36 pm
Joe Mason Mar 09, 2004 04:57 pm
Roy Smith Mar 09, 2004 05:25 pm
Joe Mason Mar 09, 2004 06:53 pm
Roy Smith Mar 09, 2004 09:05 pm
Roger Binns Mar 10, 2004 04:23 am
Roy Smith Mar 10, 2004 01:52 pm
Isaac To Mar 10, 2004 05:36 am
Jeff Epler Mar 10, 2004 01:05 pm
Isaac To Mar 10, 2004 03:58 pm
gabor Mar 10, 2004 04:34 pm
Donn Cave Mar 10, 2004 05:49 pm
Stephen Horne Mar 11, 2004 03:02 am
Jacek Generowicz Mar 11, 2004 11:40 am
Stephen Horne Mar 11, 2004 02:50 pm
Stephen Horne Mar 09, 2004 09:43 pm
Roy Smith Mar 09, 2004 09:55 pm
Stephen Horne Mar 10, 2004 12:41 am
Isaac To Mar 10, 2004 05:16 am
Christopher A. Craig Mar 08, 2004 07:54 pm
leeg Mar 09, 2004 01:34 am
Stephen Horne Mar 09, 2004 09:52 pm
leeg Mar 10, 2004 02:46 pm
Stephen Horne Mar 10, 2004 04:58 pm
Roger Binns Mar 10, 2004 06:14 pm
David MacQuigg Mar 09, 2004 11:26 pm
Anton Vredegoor Mar 10, 2004 10:11 am
Messages in this thread