5
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)
John Kugelman
  • 307,513
  • 65
  • 473
  • 519
ammhyrs
  • 53
  • 3

2 Answers2

6

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.

Ann Zen
  • 17,892
  • 6
  • 20
  • 39
4

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):
John Kugelman
  • 307,513
  • 65
  • 473
  • 519