'while' in list comprehension?

Discussion in 'Python' started by jsaul, Oct 22, 2003.

  1. jsaul

    jsaul Guest

    Hi there,

    wouldn't it be useful to have a 'while' conditional in addition to
    'if' in list comprehensions?

    foo = []
    for i in bar:
    if len(i) == 0:
    break
    foo.append(i)

    would then turn into

    foo = [ i for i in bar while len(i)>0 ]

    Is there any reason for not having this kind of thing? I actually
    miss it pretty often.

    Cheers, jsaul
     
    jsaul, Oct 22, 2003
    #1
    1. Advertising

  2. jsaul asks...
    > would then turn into
    >
    > foo = [ i for i in bar while len(i)>0 ]
    >
    > Is there any reason for not having this kind of thing? I actually
    > miss it pretty often.
    >



    How is this different from:

    foo = [ i for i in bar if len(i) ]

    Emile van Sebille
     
    Emile van Sebille, Oct 22, 2003
    #2
    1. Advertising


  3. >> foo = [ i for i in bar while len(i)>0 ]


    Emile> How is this different from:

    Emile> foo = [ i for i in bar if len(i) ]

    The first is like:

    _ = []
    for i in bar:
    if not (len(i) > 0):
    break
    _.append(i)
    return _

    The second is like:

    _ = []
    for i in bar:
    if len(i) > 0:
    _.append(i)
    return _

    Skip
     
    Skip Montanaro, Oct 22, 2003
    #3
  4. jsaul

    Bob Gailer Guest

    At 01:05 PM 10/22/2003, Emile van Sebille wrote:

    >jsaul asks...
    > > would then turn into
    > >
    > > foo = [ i for i in bar while len(i)>0 ]
    > >
    > > Is there any reason for not having this kind of thing? I actually
    > > miss it pretty often.
    > >

    >
    >
    >How is this different from:
    >
    > foo = [ i for i in bar if len(i) ]


    My reading is that the comprehension would stop at the first i whose len
    were 0. e.g.
    foo = []
    for i in bar:
    if len(i) == 0:break
    foo.append(i)

    Bob Gailer

    303 442 2625


    ---
    Outgoing mail is certified Virus Free.
    Checked by AVG anti-virus system (http://www.grisoft.com).
    Version: 6.0.525 / Virus Database: 322 - Release Date: 10/9/2003
     
    Bob Gailer, Oct 22, 2003
    #4
  5. jsaul

    Jeff Epler Guest

    Use 2.3's itertools:
    foo = [i for i in itertools.takewhile(lambda i: len(i) > 0, bar)]
    or maybe
    foo = list(itertools.takewhile(len, bar)]
    or even
    foo = itertools.takewhile(len, bar) # an iterable, not a list

    Jeff
     
    Jeff Epler, Oct 22, 2003
    #5
  6. "Emile van Sebille" <> wrote in message
    news:bn6k9i$tftt3$-berlin.de...
    > jsaul asks...
    > > would then turn into
    > >
    > > foo = [ i for i in bar while len(i)>0 ]
    > >
    > > Is there any reason for not having this kind of thing? I actually
    > > miss it pretty often.
    > >

    >
    >
    > How is this different from:
    >
    > foo = [ i for i in bar if len(i) ]
    >
    > Emile van Sebille
    >
    >


    The idea is that 'while' stops iterating through the list when the condition
    isn't met. 'if' just doesn't output anything. e.g.:

    >>> bar = ['this', 'is', 'a', 'list', '', 'see?']
    >>> [i for i in bar if len(i)]

    ['this', 'is', 'a', 'list', 'see?']
    >>> [i for i in bar while len(i)] # Pretend

    ['this', 'is', 'a', 'list']

    What's your typical use for this?

    I guess I see nothing really wrong with it, although I thought list
    comprehensions were supposed to make the iteration transparent--'while'
    kinda destroys the illusion. But these are the only two looping constructs
    that make sense in a list comprehension, so why not support both? OTOH,
    'while' makes no sense in a dictionary comprehension (and presumably we'll
    have those one day.)
     
    Francis Avila, Oct 22, 2003
    #6
  7. jsaul

    Hung Jung Lu Guest

    jsaul <> wrote in message news:<>...
    >
    > foo = [ i for i in bar while len(i)>0 ]
    >
    > Is there any reason for not having this kind of thing? I actually
    > miss it pretty often.


    Could you provide an example where you need it?

    From your message, it seems "bar" might be a list of strings. If so, you could use:

    foo = bar[:bar.index('')]

    regards,

    Hung Jung
     
    Hung Jung Lu, Oct 23, 2003
    #7
  8. jsaul

    Terry Reedy Guest

    "jsaul" <> wrote in message
    news:...
    > Hi there,
    >
    > wouldn't it be useful to have a 'while' conditional in addition to
    > 'if' in list comprehensions?
    >
    > foo = []
    > for i in bar:
    > if len(i) == 0:
    > break
    > foo.append(i)
    >
    > would then turn into
    >
    > foo = [ i for i in bar while len(i)>0 ]


    while is simply not same as if: break!
    if executes once for each value of i, while indefinitely.
    If you translate back by current rule, which will not change, you get:

    foo = []
    for i in bar:
    while len(i) >0:
    foo.append(i)

    Terry J. Reedy
     
    Terry Reedy, Oct 23, 2003
    #8
  9. On Wed, 22 Oct 2003 22:57:42 -0400, "Terry Reedy" <>
    wrote:

    >while is simply not same as if: break!
    >if executes once for each value of i, while indefinitely.
    >If you translate back by current rule, which will not change, you get:
    >


    'while' is an English word which has meaning independant of the
    existing Python 'while' loop. It is not necessarily wrong to apply a
    different aspect of that meaning in a list comprehension.

    Besides, I read the syntax as equating to...

    foo = []
    for i in bar while len(i) >0:
    foo.append(i)

    Yes, I know that isn't a legal Python loop. My point is that it didn't
    look like a nested loop to me, but rather like an additional qualifier
    on the existing loop.

    That said, you do have a point - multiple 'for' parts in a list
    comprehension act as nested loops, so maybe a while part should too.

    The trouble is that a standalone while loop probably makes little
    sense in a list comprehension - sure you have a place to put the loop
    condition, but what about the initialisation and body?

    If there were a real while-part in a list comprehension, it would
    probably need those things to become explicit (becoming a lot like the
    C for loop) - something like...

    [k while k=1; k<1024; k*=2]

    Hmmmm...

    while i=0; i<10; i++ :
    print i

    Hmmmm....

    Nah - damn silly idea.


    --
    Steve Horne

    steve at ninereeds dot fsnet dot co dot uk
     
    Stephen Horne, Oct 23, 2003
    #9
  10. jsaul

    jsaul Guest

    * Terry Reedy [2003-10-23 04:57]:
    > "jsaul" <> wrote in message
    > news:...
    > > wouldn't it be useful to have a 'while' conditional in addition to
    > > 'if' in list comprehensions?
    > >
    > > foo = []
    > > for i in bar:
    > > if len(i) == 0:
    > > break
    > > foo.append(i)
    > >
    > > would then turn into
    > >
    > > foo = [ i for i in bar while len(i)>0 ]

    >
    > while is simply not same as if: break!
    > if executes once for each value of i, while indefinitely.
    > If you translate back by current rule, which will not change, you get:
    >
    > foo = []
    > for i in bar:
    > while len(i) >0:
    > foo.append(i)


    I agree that 'while' cannot not just be considered a replacement
    for 'if'. However, adding a 'while' conditional to list
    comprehensions would very unlikely be misunderstood as another
    (infinite) loop. Instead, I find the above 'while' example about
    as intuitive as is the case with 'if'. It simply means that under
    a certain condition the loop will be ended, which is just what
    most people would probably expect.

    Anyway, thanks a lot to all who replied! What is your opinion
    after this discussion, write a PEP or just forget about it?

    Cheers, jsaul
     
    jsaul, Oct 24, 2003
    #10
  11. > > > wouldn't it be useful to have a 'while' conditional in addition to
    > > > 'if' in list comprehensions?
    > > >
    > > > foo = []
    > > > for i in bar:
    > > > if len(i) == 0:
    > > > break
    > > > foo.append(i)
    > > >
    > > > would then turn into
    > > >
    > > > foo = [ i for i in bar while len(i)>0 ]

    > >
    > > while is simply not same as if: break!
    > > if executes once for each value of i, while indefinitely.
    > > If you translate back by current rule, which will not change, you get:
    > >
    > > foo = []
    > > for i in bar:
    > > while len(i) >0:
    > > foo.append(i)

    >
    > I agree that 'while' cannot not just be considered a replacement
    > for 'if'. However, adding a 'while' conditional to list
    > comprehensions would very unlikely be misunderstood as another
    > (infinite) loop. Instead, I find the above 'while' example about
    > as intuitive as is the case with 'if'. It simply means that under
    > a certain condition the loop will be ended, which is just what
    > most people would probably expect.


    Here's an idea that might avoid this bit of confusion:

    foo = [ i for i in bar until len(i) == 0 ]

    That also makes the conditional test the same as used in the "if/break"
    form.

    Hmm... Would this mean that "until" would have to become a reserved word?
    Maybe not such a good idea if that's the case.

    -Mike
     
    Michael Geary, Oct 24, 2003
    #11
  12. jsaul

    Andrae Muys Guest

    Jeff Epler <> wrote in message news:<>...
    > Use 2.3's itertools:
    > foo = [i for i in itertools.takewhile(lambda i: len(i) > 0, bar)]
    > or maybe
    > foo = list(itertools.takewhile(len, bar)]
    > or even
    > foo = itertools.takewhile(len, bar) # an iterable, not a list
    >


    or list(takewhile(len, bar))

    from itertools import * :)

    Andrae
     
    Andrae Muys, Oct 25, 2003
    #12
  13. "Michael Geary" <> wrote in message news:<>...
    > Here's an idea that might avoid this bit of confusion:
    >
    > foo = [ i for i in bar until len(i) == 0 ]


    Another variation:

    foo = [i for i in bar, break if len(i) == 0]

    This wouldn't need a new keyword.
     
    Hannu Kankaanp??, Oct 27, 2003
    #13
  14. Hannu Kankaanp?? wrote:
    > Another variation:
    >
    > foo = [i for i in bar, break if len(i) == 0]
    >
    > This wouldn't need a new keyword.


    My thoughts on all this are that if you want to do
    something that procedural, it would be better written
    out as nested statements. List comprehensions are
    meant to be read declaratively.

    --
    Greg Ewing, Computer Science Dept,
    University of Canterbury,
    Christchurch, New Zealand
    http://www.cosc.canterbury.ac.nz/~greg
     
    Greg Ewing (using news.cis.dfn.de), Nov 13, 2003
    #14
  15. Greg Ewing (using news.cis.dfn.de) wrote:

    > Hannu Kankaanp?? wrote:
    >> Another variation:
    >>
    >> foo = [i for i in bar, break if len(i) == 0]
    >>
    >> This wouldn't need a new keyword.

    >
    > My thoughts on all this are that if you want to do
    > something that procedural, it would be better written
    > out as nested statements. List comprehensions are
    > meant to be read declaratively.


    Yes, they are. Still,

    [ i for i in bar while len(i) ]

    DOES read pretty declaratively to me (while the "break"
    version admittedly doesn't).


    Alex
     
    Alex Martelli, Nov 13, 2003
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Batista, Facundo

    RE: 'while' in list comprehension?

    Batista, Facundo, Oct 22, 2003, in forum: Python
    Replies:
    2
    Views:
    292
    Emile van Sebille
    Oct 22, 2003
  2. Batista, Facundo

    RE: 'while' in list comprehension?

    Batista, Facundo, Oct 22, 2003, in forum: Python
    Replies:
    1
    Views:
    392
    Francis Avila
    Oct 23, 2003
  3. Debajit Adhikary
    Replies:
    17
    Views:
    720
    Debajit Adhikary
    Oct 18, 2007
  4. Vedran Furac(
    Replies:
    4
    Views:
    356
    Marc 'BlackJack' Rintsch
    Dec 19, 2008
  5. Emile van Sebille

    Re: Questions: While And List Comprehension

    Emile van Sebille, Nov 10, 2010, in forum: Python
    Replies:
    4
    Views:
    240
Loading...

Share This Page