a break for comprehensions

Tom Good Tom_Good1 at excite.com
Thu Jul 26 13:36:32 EDT 2001


"Kevin Lacker" <kdl4 at acpub.duke.edu> wrote in message news:<9jpadd$s5k$1 at news.duke.edu>...
> Can you do this:
> 
> answer = []
> for x in my_list:
>     if not is_good(x):
>         break
>     answer.append(process(x))
> 
> with a list comprehension somehow? I'm starting to dislike explicit for
> loops just for the purposes of constructing another list from a current one.
> 
> Would this work in the future python with iterators...
> 
> def done(): raise StopIteration
> answer = [process(x) for x in my_list if is_good(x) or done()]
> 
> If I used it a lot it might not be a pain to define done(). I think it would
> be cool to be able to reuse the while keyword inside comprehensions like
> 
> answer = [process(x) for x in my_list while is_good(x)]
> 
> Makes sense to me... it's like being able to use a sentinel with iterators
> but more flexible.

You could simulate a "while...break" within comprehensions using a
generator, like this:

#---- begin code

def itrWhile(obj, func):
    itr = iter(obj)
    while 1:
        x = itr.next()
        if func(x):
            yield x
        else:
            return

#---- end code

Then:

>>> def isGood(n):
...     return n < 4
...
>>> a = [1,2,3,4,5,6,7]
>>> [x for x in itrWhile(a, isGood)]

[1, 2, 3]
>>>

Notice the important difference between this and "[x for x in a if
isGood(x)]"

>>> def isGood(n):
...     print "comparing", n
...     return n < 4
...
>>> [x for x in a if isGood(x)]
comparing 1
comparing 2
comparing 3
comparing 4
comparing 5
comparing 6
comparing 7
[1, 2, 3]
>>> [x for x in itrWhile(a, isGood)]
comparing 1
comparing 2
comparing 3
comparing 4
[1, 2, 3]
>>>

The "itrWhile" version breaks out after the first unsuccessful
comparison.  The version using "if" tests every element.


Tom



More information about the Python-list mailing list