Python не знает, вы просто сказали , что ожидать трех элементов, распаковав их в три имени. ValueError
говорит: «Вы сказали нам три, но мы нашли суб-итерацию, в которой не было трех элементов, и мы не знаем, что делать».
Python не делает ничего особенного для реализации этого; кроме особых случаев для встроенных типов, таких как tuple
(и, вероятно, list
), реализация состоит в том, чтобы просто выполнить итерацию итерируемого ожидаемого числа раз и вывести все значения, найденные в стеке интерпретатора, а затем сохранить их на предоставленные имена. Он также пытается выполнить итерацию еще раз (ожидая StopIteration
), чтобы вы не игнорировали лишние значения.
В ограниченных случаях вы можете проявить гибкость, указав одно из имен распаковки, начинающееся с *
, поэтому вы фиксируете все элементы "не вписываются" в это имя (как list
). Это позволяет вам установить минимальное количество элементов, в то время как позволяет больше, например, если вам действительно нужен только первый элемент из вашего второго примера, вы можете сделать:
for a, *_ in [[1,2,3],[4,5,6],[7,8,9],[0,0,0], [5]]:
print(a,b,c)
, где _
- это просто имя, которое, по соглашению, означает: «На самом деле мне не важно это значение, но мне нужно имя-заполнитель».
Другим примером может быть, когда вы хотите первый и последний элемент, но в остальном не заботитесь о середине:
for first, *middle, last in myiterable:
...
Но в противном случае, если вам нужно обрабатывать итерируемые переменные длины, не распаковывайте, просто сохраняйте под одним именем и повторяйте это имя вручную любым способом, который имеет смысл для логики вашей программы.