ammhyrs
ammhyrs

Reputation: 53

for loop - Not enough values to unpack (expected 3, got 2) but I am providing it with 3

def func(a,b,c):
    for x,y,z in a,b,c:
        pass

func(((1,2),(1,3)),((1,4),(1,5)),(1,2))

I expect x,y,z to get the values (1,2), (1,4), and 1. Instead I'm getting an error:

ValueError: not enough values to unpack (expected 3, got 2)

Upvotes: 5

Views: 295

Answers (2)

John Kugelman
John Kugelman

Reputation: 361710

a,b,c is a tuple with the parentheses implicit. It's the same as (a,b,c).

for x,y,z in (a,b,c):

This loop doesn't unpack a into x, b into y, c into z. Instead it has three iterations. The first iteration it attempts to unpack a into x,y,z. The next iteration unpacks b, and the third unpacks c.

Can a be unpacked into x,y,z? Well, a is a tuple with two elements: (1,2) and (1,3). Two elements can't be unpacked into three variables. So no, it can't. And that's why you get an error message "expected 3, got 2".

I don't know what you intend this code to do. You could perhaps fix it by wrapping (a,b,c) in an additional iterable. Either of these:

for x,y,z in ((a,b,c),):
for x,y,z in [(a,b,c)]:

Or if you want one element from each of the three, use zip to iterate over all three tuples in tandem:

for x,y,z in zip(a,b,c):

Upvotes: 4

Red
Red

Reputation: 27567

You need to zip the lists in order to do a for-loop like that without iterating through the arguments passed into func():

def func(a,b,c):
    for x,y,z in zip(a,b,c):
        pass

func(((1,2),(1,3)),((1,4),(1,5)),(1,2))

Otherwise, the for-loop will iterate through every argument passed into func.

Upvotes: 6

Related Questions