Почему я получаю ошибку Python «Too Many Values To Unpack»?

Ошибка Python «Too Many Values To Unpack» возникает, когда вы пытаетесь извлечь несколько значений из структуры данных в переменные, которые не соответствуют количеству значений. Например, если вы пытаетесь распаковать элементы списка в переменные, которые не соответствуют количеству элементов в списке.

Мы вместе рассмотрим некоторые сценарии, в которых возникает эта ошибка, например, при распаковке списков, словарей или при вызове функций Python.

Как исправить ошибку «Too Many Values To Unpack» в Python

Распространенный сценарий, в котором возникает ошибка «слишком много значений для распаковки», — это попытка распаковать значения из списка Python.

Давайте рассмотрим простой пример:

>>> week_days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
>>> day1, day2, day3 = week_days

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

Ошибка связана с тем, что значений в правой части выражения слишком много для присвоения трем переменным day1, day2 и day3.

Как видно из трассировки, это ошибка типа ValueError.

Итак, что мы можем сделать, чтобы исправить эту ошибку?

Одним из вариантов может быть использование слева ряда переменных, соответствующих числу распаковываемых значений, в данном случае пяти:

>>> day1, day2, day3, day4, day5 = week_days
>>> day1
'Monday'
>>> day5
'Friday'

На этот раз ошибки нет, и каждая переменная имеет одно из значений внутри массива week_days.

В этом примере ошибка возникла из-за того, что нам пришлось присвоить слишком много значений переменным в нашем выражении.

Давайте посмотрим, что произойдет, если у вас недостаточно значений для присвоения переменным:

>>> weekend_days = ['Saturday', 'Sunday']
>>> day1, day2, day3 = weekend_days

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

В этом примере мы пытаемся присвоить два значения трем переменным day1, day2 и day3.

Вот почему ошибка говорит «Too Many Values To Unpack (expected 3, got 2)». Потому что Python ожидает 3 значения для назначения переменным слева, но получил только 2 значения.

В этом случае правильным выражением будет:

>>> day1, day2 = weekend_days

ValueError при вызове функции Python

Та же ошибка может возникнуть при неправильном вызове функции Python.

Я определю простую функцию, которая принимает число в качестве входных данных x, и возвращает в качестве выходных данных два числа: квадрат и куб числа x.

>>> def getSquareAndCube(x):
        return x**2, x**3 
>>> square, cube = getSquareAndCube(2)
>>> square
4
>>> cube
8

Что произойдет, если по ошибке мы присвоим возвращаемые функцией значения трем переменным вместо двух?

>>> square, cube, other = getSquareAndCube(2)

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

Мы видим ошибку «Too Many Values To Unpack», поскольку значений для распаковки два, а переменных в левой части выражения три.

А что, если присвоить вывод функции одной переменной?

>>> output = getSquareAndCube(2)
>>> output
(4, 8)

Все работает хорошо, и Python делает выходную переменную кортежем, содержащим оба значения, возвращаемые функцией getSquareAndCube().

Слишком много значений для распаковки при использовании функции ввода

Другой распространенный сценарий, в котором может возникнуть эта ошибка, — это использование функции Python input() для запроса у пользователей ввода данных.

Функция Python input() считывает введенные пользователем данные и преобразует их в строку перед возвратом.

Вот простой пример:

>>> name, surname = input("Enter your name and surname: ")
Enter your name and surname: John Smith

Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    name, surname = input("Enter your name and surname: ")
ValueError: too many values to unpack (expected 2)

Почему Python жалуется на слишком большое количество значений для распаковки?

Это связано с тем, что функция input() преобразует входные данные в строку, в данном случае «Джон Смит», а затем пытается присвоить каждый символ строки переменным слева.

Итак, у нас есть несколько символов в правой части выражения, которые присваиваются двум переменным, поэтому Python говорит, что ожидает два значения.

Что мы можем с этим сделать?

Мы можем применить строковый метод split() к выходным данным входной функции:

>>> name, surname = input("Enter your name and surname: ").split()
Enter your name and surname: John Smith
>>> name
'John'
>>> surname
'Smith'

Метод split преобразует строку, возвращаемую функцией ввода, в список строк, а два элемента списка присваиваются переменным name и favorite.

По умолчанию метод split использует пробел в качестве разделителя. Если вы хотите использовать другой разделитель, вы можете передать его в качестве первого параметра методу split.

Использование Maxsplit для решения ошибки Python «Too Many Values To Unpack»

Есть еще один способ решения проблемы, которую мы наблюдали при распаковке списка.

Давайте начнем снова со следующего кода:

>>> name, surname = input("Enter your name and surname: ").split()

На этот раз мы предоставим другой строке для функции ввода:

Enter your name and surname: Mr John Smith

Traceback (most recent call last):
  File "<pyshell#29>", line 1, in <module>
    name, surname = input("Enter your name and surname: ").split()
ValueError: too many values to unpack (expected 2)

Аналогично, как мы видели ранее, эта ошибка возникает, потому что split() преобразует входную строку в список из трех элементов. А три элемента не могут быть назначены двум переменным.

Есть способ заставить Python разбить строку, возвращаемую функцией ввода, на значения, соответствующие количеству переменных, в данном случае двум.

Вот общий синтаксис метода split(), который позволяет это сделать:

<string>.split(separator, maxsplit)

Параметр maxsplit определяет максимальное количество разделений, используемых методом Python split при преобразовании строки в список. Maxsplit — необязательный параметр.

Итак, в нашем случае давайте посмотрим, что произойдет, если мы установим maxsplit равным 1.

>>> name, surname = input("Enter your name and surname: ").split(' ', 1)

Enter your name and surname: Mr John Smith
>>> name
'Mr'
>>> surname
'John Smith'

Ошибка исчезла, логика этой строки не идеальна, учитывая, что surname это ‘Джон Смит’. Но это всего лишь пример, показывающий, как работает maxsplit.

Итак, почему мы устанавливаем maxsplit на 1?

Поскольку в этом случае строка, возвращаемая функцией ввода, разделяется только один раз при преобразовании в список, это означает, что результатом является список из двух элементов (соответствующих двум переменным в левой части нашего выражения).

Слишком много значений для распаковки при итерации по словарю

В последнем примере мы воспользуемся словарем Python, чтобы объяснить еще одну распространенную ошибку, которая возникает при разработке.

Я создал простую программу для вывода каждого ключа и значения в словаре users:

users = {
    'username': 'jsmith',
    'name': 'John',
}

for key, value in users:
    print(key, value)

При запуске вы увидите следующую ошибку:

$ python dict_example.py

Traceback (most recent call last):
  File "dict_example.py", line 6, in <module>
    for key, value in users:
ValueError: too many values to unpack (expected 2)

В чем проблема?

Давайте попробуем выполнить цикл for, используя только одну переменную:

for key in users:
    print(key)

Вывод:

$ python dict_example.py
username
name

Когда мы проходим по словарю, используя его имя, мы получаем только ключи.

Вот почему раньше мы видели ошибку: мы пытались распаковать каждый ключ в две переменные: ключ и значение.

Чтобы извлечь каждый ключ и значение из словаря, нам нужно использовать метод dictionary items().

Давайте выполним следующее:

for user in users.items():
    print(user)

На этот раз вывод такой:

('username', 'jsmith')
('name', 'John')

На каждой итерации цикла for мы получаем кортеж, содержащий ключ и его значение. Этот кортеж можно присвоить двум переменным, которые мы использовали ранее.

Итак, программа становится такой:

users = {
    'username': 'jsmith',
    'name': 'John',
}

for key, value in users.items():
    print(key, value)

Программа выводит следующий результат:

$ python dict_example.py
username jsmith
name John

Все хорошо, ошибка исправлена!

А вы? Где вы видите эту ошибку?

Дайте мне знать в комментариях ниже.