Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ValueError: too many values to unpack

Tags:

python

loops

why this code is wrong?

for i,j in range(100),range(200,300):
    print i,j

when I test this for statement I see this error

ValueError: too many values to unpack

but when I test

for i, j in range(2),range(2):
     print i,j

every thing is correct!

like image 517
Vahid Kharazi Avatar asked Nov 08 '12 22:11

Vahid Kharazi


3 Answers

range(2) gives a list [0, 1]. So, your i, j will be fetched from first list and and then from the second list.

So, your loop is similar to: -

for i, j in [0, 1], [0, 1]:
    print i, j

Prints: -

0 1
0 1

Now, if you have range(3) there, then it will fail, because, range(3) gives a 3-element list, which cannot be unpacked in two loop variables.

So, you cannot do: -

for (i, j) in [[0, 1, 2]]:
    print i, j

It will fail, giving you the error that you are getting.

Try using zip, to zip your both list into one.: -

>>> for (i, j) in (zip(range(2), range(3))):
    print i, j


0 0
1 1
>>> 

zip converts your lists into list of tuples with 2 elements in the above case, as you are zipping 2 lists.

>>> zip(range(2), range(3))
[(0, 0), (1, 1)]

Similarly, if you zip three lists, you will get list of 3-elements tuple.

like image 130
Rohit Jain Avatar answered Oct 02 '22 08:10

Rohit Jain


range(200), range(300) is too long to look at, but we can understand that case by looking at range(2), range(3) instead[1]:

iterable = (range(2), range(3))
print(iterable)
for i, j in iterable:
     print(repr(i))

first prints

([0, 1], [0, 1, 2])    #<-- This is what your iterable looks like
0

then raises

ValueError: too many values to unpack

In the first pass through the loop, i equals 0 and j equals 1. In the second pass, i,j is assigned to [0,1,2]. Clearly there are too many values to unpack, hence the exception.


Footnote[1]:

for i, j in range(2), range(3):

is equivalent to

for i, j in (range(2), range(3)):

which is equivalent to

iterable = (range(2), range(3))
for i, j in iterable:
like image 30
unutbu Avatar answered Oct 02 '22 06:10

unutbu


Try using zip:

for i, j in zip(range(2),range(2)):
     print i,j

That's just the Python syntax. If you want to have two loop variables, the iterated object must contain sequences with length of two. Your statement, however, is the same as:

i, j = range(100)

You're iterating over the sequence [range(100), range(100)]. The first iteration returns range(100), and as you can see by the previous example, that obviously fails.

It works with range(2) because that returns a sequence with the length of two that your i,j statement can be unpacked to.

like image 31
kichik Avatar answered Oct 02 '22 07:10

kichik