"too many values to unpack (expected 2)" when the len of element in array is more than 2

Viewed 1825

Maybe it would be weird to ask this question, as certainly I don't understand it.

for example, if we have a=[(1,2), (3,4)]; the operation works

for x,y in a:
    print(x,y)

But as soon as the we add any further elements to those tuples, a=[(1,2,3),(4,5,6)]

for x,y in a:
    print(x,y)
---------------
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 2)

But working with zip(a[0],a[1]) works

I see that this question has been asked many times before but I couldn't find any that takes on why len with more than 2 doesn't work.

can anyone explain to me as to why it is?

4 Answers

Good question.

In the case of a=[(1,2), (3,4)], it is important to understand what these data structures are.

a is a list of tuples. So a[0] is (1,2) and a[1] is (3,4)

So if you add more elements to one of the tuples, you are effectively not changing a. Because, remember, a is simply the tuples. You are changing the values within the tuples. So therefore, a's length never changes.

If you want to access the values of said tuples, you could do print(a[0][0]) which yields 0

An example program to see what I mean:

a = [(1,2), (3,4)]
b = [(1,2,3), (4,5,6)]

def understand_data(x):
    print("First, let's loop through the first structure and see what it is")
    print("You passed in: {}".format(type(x)))


    print("Now printing type and contents of the passed in object")
    for i in range(len(x)):
        print(type(x[i]))
        print(x[i])

    print("Now printing the contents of the contents of the passed in object")
    for i in range(len(x)):
        for j in range(len(x[i])):
            print(x[i][j])

    print("DONE!")

understand_data(a)
understand_data(b)

Yields:

[Running] python -u "c:\Users\Kelly\wundermahn\example.py"
First, let's loop through the first structure and see what it is
You passed in: <class 'list'>
Now printing type and contents of the passed in object
<class 'tuple'>
(1, 2)
<class 'tuple'>
(3, 4)
Now printing the contents of the contents of the passed in object
1
2
3
4
DONE!
First, let's loop through the first structure and see what it is
You passed in: <class 'list'>
Now printing type and contents of the passed in object
<class 'tuple'>
(1, 2, 3)
<class 'tuple'>
(4, 5, 6)
Now printing the contents of the contents of the passed in object
1
2
3
4
5
6
DONE!

[Done] exited with code=0 in 0.054 seconds

too many values to unpack is thrown since you are trying to unpack (assign to variables) tuples of 3 element into 2 variables - x and y.

If your tuples consist of n elements, you should unpack them with n variables so in your case:

for x,y,z in a:
    pass

The reason why zip(a[0],a[1]) works for you is because zip creates an iterator of 2 elements tuples in your example. If you change it to zip(a[0],a[1], a[2]) for example, it wouldn't work because iterator of 3 elements tuples will be created and 2 variable won't be enough to unpack it.

Firstly, try:

a = [(1, 2, 3), (4, 5, 6)]
for i in a:
    x, y, z = i
    print(x, y, z)

It should return:

1 2 3
4 5 6

Variable x plays as a shipper, who brings 3 boxes from warehouse a to 3 different customers x, y, y. Next, if the shipper quits the job, then the 3 persons need to go to warehouse themself. So, we have a change:

a = [(1, 2, 3), (4, 5, 6)]
for x, y, z in a:
    print(x, y, z)

It returns the same result as above.
Bonus, if there are only 2 customers to receive 3 boxes. x gets one box and y gets two left.

a = [(1, 2, 3), (4, 5, 6)]
for x, *y in a:
    print(x, y)

The output:

1 [2, 3]
4 [5, 6]

Hope it useful!

Because the tuples in a have three elements each, you'll need three variables to unpack them. That is,

for x,y,z in a:
    ...

The reason why your zip example works is because zip creates a tuple out of the individual elements of the iterables (in this case, the tuples). There are only two iterables being passed to zip (i.e., a[0] and a[1]). That's why you only need two variables to unpack them.

To better see this, try running this code:

for x in a:
    print(x)

You'll see that you need three variables to represent the individual values of x.

Then take a look at the output of:

for x in zip(a[0],a[1]):
    print(x)
Related