Unpaking Tuple

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sat Oct 6 11:08:38 EDT 2012


On Sat, 06 Oct 2012 08:46:28 -0400, Roy Smith wrote:

> In article <mailman.1898.1349519275.27098.python-list at python.org>,
>  Chris Rebert <clp2 at rebertia.com> wrote:
> 
>> But at any rate:
>> shortfall = 4 - len(your_tuple)
>> your_tuple += (None,) * shortfall # assuming None is a suitable default
>> a, b, c, d = your_tuple
>> 
>> If you also need to handle the "too many items" case, use slicing: a,
>> b, c, d = your_tuple[:4]
> 
> I usually handle both of those cases at the same time:
> 
>>>> a, b, c, d = (my_tuple + (None,) * 4)[:4]


While that's fine for small tuples, if somebody wanted to mess with you, 
and passed (say) a million-item tuple, that would unnecessarily copy all 
million items before throwing all but four away.

For the sake of a two-liner instead of a one-liner, you can avoid such 
nasty surprises:

my_tuple = my_tuple[:4]
a,b,c,d = my_tuple if len(my_tuple) == 4 else (my_tuple + (None,)*4)[:4]

A similar solution:

a,b,c,d = (my_tuple[:4] + (None, None, None, None))[:4]

Here's a dumb one-liner, good for making people laugh at you:

a,b,c,d = (x for i,x in enumerate(my_tuple + (None,)*4) if i < 4)

and an obfuscated solution:

from itertools import izip_longest as izip
a,b,c,d = (None if x == (None,None) else x[0][1] for x in izip(zip
('izip', my_tuple), (None for izip in 'izip')))


But in my opinion, the best solution of all is a three-liner:

if len(my_tuple) < 4:
    my_tuple += (None,)*(4 - len(my_tuple))
a,b,c,d = my_tuple[4:]



-- 
Steven



More information about the Python-list mailing list