# Dynamic unpacking in Python

Python lacks dynamic unpacking. Example: You want to unpack a list, let's say coordinates, but don't know whether it contains 3 items or just 2.

x, y, z = [1,2,3] works only if len([x,y,z]) == len([1,2,3]).

x, y, z = [1,2] results in an error. You could add try and except blocks but that could be complicated.

The best option is z being None, as you can simply check using if n is None without any excessive try/except.

So expected result:

>>> x, y, z = unpack([1,2])
>>> print(x)
1
>>> print(y)
2
>>> print(z)
None


## My code

def unpack(num, list):
return_arr = [None] * num
for i,elem in enumerate(list):
return_arr[i] = elem
if i+1 == num:
return return_arr
return return_arr


And usage examples:

a,b,c,d = unpack(4, [1,2,3])
print(a),
print(b),
print(c),
print(d),
print("\n")

e,f,g = unpack(3, [1,2,3])
print(e),
print(f),
print(g)


resulting in

1 2 3 None

1 2 3


You basically have to specify the amount of variables you're unpacking the list to, since the function can't know that.

• I'm wondering if it would be possible to create a class for iterables that will unpack dynamically (by magically having the right length or something). I've been trying to answer this, but I couldn't. Oct 16 '16 at 21:53
• @OskarSkog Just replace the __iter__ method of your class by this unpack (granted you make it return an iterator). Oct 16 '16 at 22:02
• @OskarSkog Nevermind, not really as you can't pass the number of variable you want to unpack into to the __iter__ method, but I would start digging in that direction anyway. Oct 16 '16 at 22:04
• I just started thinking about it and realised that an infinite iterable would be easy to make but that would have too many value to unpack. I guess "Python lacks dynamic unpacking." really means what it means. Oct 16 '16 at 22:08

1. It is generaly a bad idea to shadow a builtin (like list) by using a variable named after it.
2. You can use slices and array extension to simplify a bit your algorithm:

def unpack(n, lst):
result = lst[:n]
return result + [None] * (n - len(result))

3. You can use the itertools module to improve memory management and allow for any iterable:

import itertools

def unpack(n, iterable):
infinite = itertools.chain(iterable, itertools.repeat(None))
return itertools.islice(infinite, n)

4. Python 3 has an extended unpacking capability that is closer to your needs:

>>> x, y, *z = [1, 2]
>>> print(x, y, z)
1, 2, []

• Awesome point, didn't realize I can just return a slice and each part of the rest as None. Thanks a lot. Oct 17 '16 at 14:59
1. The function has no docstring. What does it do? How do I call it? Are there any helpful examples you can present? The text in the post would make a good start.

2. The name unpack is poorly chosen. I know that sequence unpacking is the use case that you have in mind, but the function does not actually unpack anything. What it does is to return a fixed-length prefix of a sequence, padding with None if necessary to make it up to the required length. So a name like prefix_pad_none would give a clearer indication of the behaviour. (Compare with the padnone recipe in the itertools documentation.)

3. The pad value None should be a parameter to the function (with default value of None). That's because there are use cases in which you might want to pad a sequence with some other value. For example, zero, one, and NaN are common pad values in mathematical code.

Revised code:

from itertools import chain, islice, repeat