Re: unpacking first few items of iterable

Discussion in 'Python' started by Peter Otten, Dec 13, 2012.

  1. Peter Otten

    Peter Otten Guest

    Terry Reedy wrote:

    > On 12/13/2012 3:09 PM, MRAB wrote:
    >> On 2012-12-13 19:37, Daniel Fetchinson wrote:
    >>> Hi folks, I swear I used to know this but can't find it anywhere:
    >>>
    >>> What's the standard idiom for unpacking the first few items of an
    >>> iterable whose total length is unknown?

    >
    > An hinted by some of the answers, this is not a complete specification.
    >
    >>> Something like
    >>>
    >>> a, b, c, _ = myiterable
    >>>
    >>> where _ could eat up a variable number of items, in case I'm only
    >>> interested in the first 3 items?

    >
    > The literal answer given by demian, a,b,c,*_=iterable, has some good
    > uses but fails on an infinite iterable, and otherwise exhausts iterators
    > and creates a potentially long sequence that, by the specification, is
    > not needed. Mitya's alternative of slicing, seq[:3] requires a directly
    > sliceable sequence rather than just an iterable.
    >
    >> You could do this:
    >>
    >> from itertools import islice
    >> a, b, c = islice(myiterable, 3)

    >
    > This works for any iterable and the only discarded temporary is a
    > sequence of three items (needed so either all bindings work or none are
    > made).
    >
    > If you want to bind a default values if iterable has less than 3 values,
    > one way is
    >
    > >>> a,b,c = itertools.islice(itertools.chain(itertools.islice((1,2),

    > 3), [None]*3), 3)
    > >>> a,b,c

    > (1, 2, None)


    If something doesn't look natural I usually shuffle around my code a bit. In
    this case I might end up with a helper function:

    def work_with_abc(a=None, b=None, c=None, *discarded):
    ...
    work_with_abc(*myiterable)

    > Perhaps clearer is
    >
    > >>> a,b,c = [None]*3
    > >>> it = iter((1,2))
    > >>> try:

    > a = next(it)
    > b = next(it)
    > c = next(it)
    > except StopIteration:
    > pass
    >
    > >>> a,b,c

    > (1, 2, None)


    Or

    it = iter(myiterable)
    a = next(it, None)
    b = next(it, None)
    c = next(it, None)

    > This has the advantage that if iterable has more than 3 items, 'it' is
    > available to iterate over the rest. This is the standard idiom for
    > removing a couple of special items before iterating over the remainder
    > (when one does not want the remainder as a concrete list).
     
    Peter Otten, Dec 13, 2012
    #1
    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. Daniel Fetchinson

    unpacking first few items of iterable

    Daniel Fetchinson, Dec 13, 2012, in forum: Python
    Replies:
    0
    Views:
    138
    Daniel Fetchinson
    Dec 13, 2012
  2. Demian Brecht

    Re: unpacking first few items of iterable

    Demian Brecht, Dec 13, 2012, in forum: Python
    Replies:
    0
    Views:
    143
    Demian Brecht
    Dec 13, 2012
  3. MRAB
    Replies:
    0
    Views:
    150
  4. Daniel Fetchinson

    Re: unpacking first few items of iterable

    Daniel Fetchinson, Dec 13, 2012, in forum: Python
    Replies:
    0
    Views:
    152
    Daniel Fetchinson
    Dec 13, 2012
  5. Mitya Sirenef

    Re: unpacking first few items of iterable

    Mitya Sirenef, Dec 13, 2012, in forum: Python
    Replies:
    0
    Views:
    143
    Mitya Sirenef
    Dec 13, 2012
Loading...

Share This Page