Search code examples
pythoniterable-unpacking

Unpack value(s) into variable(s) or None (ValueError: not enough values to unpack)


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
>>>

Solution

  • 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.