Gmail Calendar Documents Reader Web more »
Recently Visited Groups | Help | Sign in
Google Groups Home
PEP on breaking outer loops with StopIteration
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  7 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Kris Kowal  
View profile  
 More options Jun 9 2008, 9:07 pm
Newsgroups: comp.lang.python
From: "Kris Kowal" <kris.ko...@cixar.com>
Date: Mon, 9 Jun 2008 18:07:30 -0700
Local: Mon, Jun 9 2008 9:07 pm
Subject: PEP on breaking outer loops with StopIteration
I had a thought that might be pepworthy.  Might we be able to break
outer loops using an iter-instance specific StopIteration type?

This is the desired, if not desirable, syntax::

    import string
    letters = iter(string.lowercase)
    for letter in letters:
        for number in range(10):
            print letter, number
            if letter == 'a' and number == 5:
                raise StopIteration()
            if letter == 'b' and number == 5:
                raise letters.StopIteration()

The first StopIteration would halt the inner loop.  The second
StopIteration would halt the outer loop.  The inner for-loop would
note that the letters.StopIteration instance is specifically targeted
at another iteration and raise it back up.

For this output::

    a 0
    a 1
    a 2
    a 3
    a 4
    a 5
    b 0
    b 1
    b 2
    b 3
    b 4
    b 5

This could be incrementally refined with the addition of an "as"
clause to "for" that would be bound after an iterable is implicitly
iter()ed::

    import string
    for letter in string.lowercase as letters:
        …
        raise letters.StopIteration()

I took the liberty to create a demo using a "for_in" decorator instead
of a "for" loop::

    former_iter = iter

    class iter(object):
        def __init__(self, values):
            if hasattr(values, 'next'):
                self.iter = values
            else:
                self.iter = former_iter(values)
            class Stop(StopIteration):
                pass
            if hasattr(values, 'StopIteration'):
                self.StopIteration = values.StopIteration
            else:
                self.StopIteration = Stop

        def next(self):
            try:
                return self.iter.next()
            except StopIteration, exception:
                raise self.StopIteration()

    def for_in(values):
        def decorate(function):
            iteration = iter(values)
            while True:
                try:
                    function(iteration.next())
                except iteration.StopIteration:
                    break
                except StopIteration, exception:
                    if type(exception) is StopIteration:
                        break
                    else:
                        raise
        return decorate

    import string
    letters = iter(string.lowercase)

    @for_in(letters)
    def _as(letter):
        @for_in(range(10))
        def _as(number):
            print letter, number
            if letter == 'a' and number == 5:
                raise StopIteration()
            if letter == 'b' and number == 5:
                raise letters.StopIteration()

I imagine that this would constitute a lot of overhead in
StopIteration type instances, but perhaps a C implementation would use
flyweight StopIteration types for immutable direct subtypes of the
builtin StopIteration.

Kris Kowal


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Paul Hankin  
View profile  
 More options Jun 9 2008, 10:39 pm
Newsgroups: comp.lang.python
From: Paul Hankin <paul.han...@gmail.com>
Date: Mon, 9 Jun 2008 19:39:07 -0700 (PDT)
Local: Mon, Jun 9 2008 10:39 pm
Subject: Re: PEP on breaking outer loops with StopIteration
On Jun 10, 10:07 am, "Kris Kowal" <kris.ko...@cixar.com> wrote:

> I had a thought that might be pepworthy.  Might we be able to break
> outer loops using an iter-instance specific StopIteration type?

> This is the desired, if not desirable, syntax::

>     import string
>     letters = iter(string.lowercase)
>     for letter in letters:
>         for number in range(10):
>             print letter, number
>             if letter == 'a' and number == 5:
>                 raise StopIteration()
>             if letter == 'b' and number == 5:
>                 raise letters.StopIteration()

Have you checked out http://www.python.org/dev/peps/pep-3136/

It contains exactly this idea, but using 'break letters' rather than
'raise letters.StopIteration()'. I think I like the PEP's syntax
better than yours, but anyway, it was rejected.

--
Paul Hankin


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kris Kowal  
View profile  
 More options Jun 10 2008, 1:21 am
Newsgroups: comp.lang.python
From: "Kris Kowal" <k...@cixar.com>
Date: Mon, 9 Jun 2008 22:21:37 -0700
Local: Tues, Jun 10 2008 1:21 am
Subject: Re: PEP on breaking outer loops with StopIteration

On Mon, Jun 9, 2008 at 7:39 PM, Paul Hankin <paul.han...@gmail.com> wrote:
> Have you checked out http://www.python.org/dev/peps/pep-3136/

> It contains exactly this idea, but using 'break letters' rather than
> 'raise letters.StopIteration()'. I think I like the PEP's syntax
> better than yours, but anyway, it was rejected.

I concur that "break letters" is better than "raise
letters.StopIteration()".  Perhaps the novelty of the implementation
idea (adding another exception case to the "while: try" that
must already be there, and the specialized exception type) can wake this
dead issue.  Maybe "break letters" could under the hood raise the
specialized StopIteration.

But, then again.  Guido has said, "No", already on other, albeit
subjective, grounds.
I'll drop it or champion it if there's interest.

Kris Kowal


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Luis Zarrabeitia  
View profile  
 More options Jun 10 2008, 1:29 am
Newsgroups: comp.lang.python
From: Luis Zarrabeitia <ky...@uh.cu>
Date: Tue, 10 Jun 2008 01:29:43 -0400
Local: Tues, Jun 10 2008 1:29 am
Subject: Re: PEP on breaking outer loops with StopIteration

Quoting Kris Kowal <kris.ko...@cixar.com>:

> I had a thought that might be pepworthy.  Might we be able to break
> outer loops using an iter-instance specific StopIteration type?

> This is the desired, if not desirable, syntax::

>     import string
>     letters = iter(string.lowercase)
>     for letter in letters:
>         for number in range(10):
>             print letter, number
>             if letter == 'a' and number == 5:
>                 raise StopIteration()
>             if letter == 'b' and number == 5:
>                 raise letters.StopIteration()

I must say, I don't even like the idea of having a 'break', but I kind of like
this proposal.

However, it may be ambiguous [is that a word?] if the outer and inner for loop
over the same object. Weird/unlikely situation, I know... but so is having a
deep break :D.

--
Luis Zarrabeitia
Facultad de Matemática y Computación, UH
http://profesores.matcom.uh.cu/~kyrie


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Dan Bishop  
View profile  
 More options Jun 10 2008, 1:50 am
Newsgroups: comp.lang.python
From: Dan Bishop <danb...@yahoo.com>
Date: Mon, 9 Jun 2008 22:50:01 -0700 (PDT)
Local: Tues, Jun 10 2008 1:50 am
Subject: Re: PEP on breaking outer loops with StopIteration
On Jun 9, 8:07 pm, "Kris Kowal" <kris.ko...@cixar.com> wrote:

> I had a thought that might be pepworthy.  Might we be able to break
> outer loops using an iter-instance specific StopIteration type?

> This is the desired, if not desirable, syntax::

>     import string
>     letters = iter(string.lowercase)
>     for letter in letters:
>         for number in range(10):
>             print letter, number
>             if letter == 'a' and number == 5:
>                 raise StopIteration()
>             if letter == 'b' and number == 5:
>                 raise letters.StopIteration()

You can break out of outer loops now with the proper (ab)use of
exceptions:

class BreakOuter(Exception):
    pass

try:
    for letter in string.lowercase:
        for number in xrange(10):
            print letter, number
            if letter == 'a' and number == 5:
                break
            if letter == 'b' and number == 5:
                raise BreakOuter()
except BreakOuter:
    pass

Or, for consistency:

class BreakInner(Exception):
    pass

class BreakOuter(Exception):
    pass

try:
    for letter in string.lowercase:
        try:
            for number in xrange(10):
                print letter, number
                if letter == 'a' and number == 5:
                    raise BreakInner()
                if letter == 'b' and number == 5:
                    raise BreakOuter()
        except BreakInner:
            pass
except BreakOuter:
    pass


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Diez B. Roggisch  
View profile  
 More options Jun 10 2008, 2:51 am
Newsgroups: comp.lang.python
From: "Diez B. Roggisch" <de...@nospam.web.de>
Date: Tue, 10 Jun 2008 08:51:00 +0200
Subject: Re: PEP on breaking outer loops with StopIteration
Kris Kowal schrieb:

For the record: I share GvR's opinion on the general usefulness.

Additionally, your syntax is impossible. There isn't always a containing
variable for the iterable.

And if you meant "letter", it's ambigous. It is perfectly legal in
python to do this:

class Foo(object):
     StopIteration = StopIteration

for letter in [Foo(), Foo()]:
     for number in range(10):
         raise letter.StopIteration

Diez


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
nwinters3...@gmail.com  
View profile  
 More options Jun 10 2008, 9:47 am
Newsgroups: comp.lang.python
From: nwinters3...@gmail.com
Date: Tue, 10 Jun 2008 06:47:13 -0700 (PDT)
Local: Tues, Jun 10 2008 9:47 am
Subject: Re: PEP on breaking outer loops with StopIteration
On Jun 9, 10:50 pm, Dan Bishop <danb...@yahoo.com> wrote:

I prefer having a new function wrapping the inner loop and using both
break and return, but this doesn't allow you to "break 1 loop up and 2
loops up", and doesn't help to continue a particular loop further up

def innerLoop(letter):
   for number in xrange(10):
      print letter, number
      if letter == 'a' and number == 5:
         break
      if letter == 'b' and number == 5:
         return

for letter in string.lowercase:
   innerLoop(letter)

In response to the suggested syntax, I have found occasions where I
iterate through the same variable [say searching for duplicates within
some tolerance to merge into one item] in an inner loop.  I also don't
see how it would extend to something like:

for evenNumber in [x*2+1 for x in xrange(5)]: print evenNumber


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2009 Google