Velocity Reviews > Best idiom to unpack a variable-size sequence

# Best idiom to unpack a variable-size sequence

ram
Guest
Posts: n/a

 12-18-2007
Here's a little issue I run into more than I like: I often need to
unpack a sequence that may be too short or too long into a fixed-size
set of items:

a, b, c = seq # when seq = (1, 2, 3, 4, ...) or seq = (1, 2)

What I usually do is something like this:

a, b, c = (list(seq) + [None, None, None])[:3]

but that just feels rather ugly to me -- is there a good Pythonic
idiom for this?

Thx,
Rick

George Sakkis
Guest
Posts: n/a

 12-18-2007
On Dec 18, 12:49 pm, ram <(E-Mail Removed)> wrote:
> Here's a little issue I run into more than I like: I often need to
> unpack a sequence that may be too short or too long into a fixed-size
> set of items:
>
> a, b, c = seq # when seq = (1, 2, 3, 4, ...) or seq = (1, 2)
>
> What I usually do is something like this:
>
> a, b, c = (list(seq) + [None, None, None])[:3]
>
> but that just feels rather ugly to me -- is there a good Pythonic
> idiom for this?

In terms of brevity I don't think so; however it can be done more
efficient and general (e.g. for infinite series) using itertools:

from itertools import islice, chain, repeat

def unpack(iterable, n, default=None):
return islice(chain(iterable,repeat(default)), n)

a, b, c = unpack(seq, 3)

George

Duncan Booth
Guest
Posts: n/a

 12-18-2007
ram <(E-Mail Removed)> wrote:

> Here's a little issue I run into more than I like: I often need to
> unpack a sequence that may be too short or too long into a fixed-size
> set of items:
>
> a, b, c = seq # when seq = (1, 2, 3, 4, ...) or seq = (1, 2)
>
> What I usually do is something like this:
>
> a, b, c = (list(seq) + [None, None, None])[:3]
>
> but that just feels rather ugly to me -- is there a good Pythonic
> idiom for this?

Pythonic might be to be explicit: i.e. know in advance how long the
sequence actually is.

One drawback I see with your code is that it doesn't give you any way to
specify different defaults for the values. So here's an alternative to
consider: try passing your sequence to a function. This lets you specify
appropriate defaults, and it reads quite cleanly. Of course it also forces
you to extract the code using those variables out into a separate function,
but that may not be a bad thing.

>>> def process(a=None, b=None, c=None):

print a, b, c

>>> seq = iter('abcd')
>>> process(*itertools.islice(seq,0,3))

a b c
>>> seq = iter('ab')
>>> process(*itertools.islice(seq,0,3))

a b None
>>>