PythonMastery
reference 3 min read · lesson 15 of 60 in Errors

ValueError: too many values to unpack

1 · The lesson

read

What this error means

You tried to unpack an iterable into a fixed number of variables, but the iterable had more items than variables. Python expected exactly as many items on the right as names on the left.

When you see it

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

Why it happens

Unpacking assignment is strict by default: a, b = iterable requires iterable to yield exactly two items. If it yields three, four, or more, Python doesn't know what to do with the extra items, and it refuses to silently throw them away.

How to fix it

1. Use a starred target to collect the rest:

python
a, b, *rest = [1, 2, 3, 4]
# a=1, b=2, rest=[3, 4]

The star can be in any position:

python
first, *middle, last = [1, 2, 3, 4]
# first=1, middle=[2, 3], last=4

2. Discard unwanted values with _:

python
a, b, _ = [1, 2, 3]            # ignore the third
a, b, *_ = [1, 2, 3, 4, 5]     # ignore all extras

3. Slice or index when you only want specific elements:

python
parts = "a,b,c,d".split(",")
first, second = parts[0], parts[1]

4. Check that your data really has the shape you expect:

python
print(len(row), row)   # debug before unpacking
+ setup added so this can run · defines row
# Lightweight mock for objects whose attributes/methods aren't critical
class _AutoMock:
    def __init__(self, name='mock'): self._name = name
    def __getattr__(self, k): return _AutoMock(self._name + '.' + k)
    def __call__(self, *a, **kw):
        print('-> ' + self._name + '() called')
        return _AutoMock(self._name + '()')
    def __repr__(self): return '<mock ' + self._name + '>'
    def __str__(self): return '<mock ' + self._name + '>'
    def __bool__(self): return True
    def __iter__(self): return iter([])
    def __len__(self): return 0
    def __getitem__(self, k): return _AutoMock(self._name + '[...]')
    def __setitem__(self, k, v): pass
    def __enter__(self): return self
    def __exit__(self, *a): return False
    async def __aenter__(self): return self
    async def __aexit__(self, *a): return False
    def __add__(self, o): return self
    def __radd__(self, o): return self
    def __sub__(self, o): return self
    def __mul__(self, o): return self
    def __rmul__(self, o): return self
    def __truediv__(self, o): return self
    def __eq__(self, o): return isinstance(o, _AutoMock)
    def __hash__(self): return hash(self._name)
    def __lt__(self, o): return True
    def __le__(self, o): return True
    def __gt__(self, o): return False
    def __ge__(self, o): return False
    def __mro_entries__(self, bases): return (object,)

row = _AutoMock('row')

When you'd see this in real code

  • Parsing CSV rows: name, age = line.split(",") fails as soon as a row has a comma inside a quoted field. Use the csv module instead.
  • Splitting a full name: first, last = name.split(" ") fails on "John Paul Jones". Use first, *rest = name.split(" ") or name.split(" ", 1).
  • Iterating a dict with the wrong shape: for key in d.items(): gives you (k, v) tuples, and for k, v in d.items(): works. But for k, v in d: loops over the keys only, so a key like "name" is unpacked into two names and raises this error.

See Also

Practice this

on practicepython.in

Short exercises that run in your browser and tell you what your code did, as well as whether a test passed.

Found this useful? Share it with a friend who’s learning Python.