9

How should an iterable be unpacked into a mismatching number of variable(s)?

Too many values:

>>> one,two = [1,2,3]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 2)

can be ignored with

>>> one,two,*_ = [1,2,3,4]  
>>> 

Note: "extended iterable unpacking" since Python 3 only. About the underscore.

How can the opposite case of too few data / more variables:

>>> one,two,three = [1,2]   
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: not enough values to unpack (expected 3, got 2)
>>>

be handled, specifically so that the remaining variables are assigned None (or some other value)?

Something like this:

>>> one,two,three = [1,2] or None
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: not enough values to unpack (expected 3, got 2)
>>>


https://stackoverflow.com/a/8857846/1619432 suggests expanding the list:
>>> one,two,three = [1,2] + [None]*(3-2)
>>> one   
1
>>> two
2
>>> three
>>>
handle
  • 5,859
  • 3
  • 54
  • 82

3 Answers3

15

You can unpack a sequence to three variable using:

one, two, *three = [1,2]

At this point, three will be an empty list. You can then assign three to None using an or check if three is empty.

three = three or None
James
  • 32,991
  • 4
  • 47
  • 70
5

Use the * operator and fill an intermediate iterable with that which you're unpacking and fill the remainder with your default value of choice.

x = [1, 2]
default_value= None
one, two, three = [*x, *([default_value] * (3 - len(x)))]

And a bonus function to handle both cases:

def unpack(source, target, default_value=None):
    n = len(source)
    if n < target:
        return [*source, *([default_value] * (target - len(source)))]
    elif n > target:
        return source[0:target]
    else:
        return source

Amend to handle non-iterable input as needed.

Neuron
  • 5,141
  • 5
  • 38
  • 59
pkfm
  • 451
  • 3
  • 7
5

Does this work for you? You can make the nones array as big as you need.

nones = [None]*100 # or however many you think you might need
one, two, three, four, five, *_ = [1,2] + nones
igg
  • 2,172
  • 3
  • 10
  • 33