[ACCEPTED]-ValueError: need more than 2 values to unpack in Python 2.6.6-python

Accepted answer
Score: 20

Instead of unpacking in your assignment:

a, b, c = do_something()

Try 2 assigning the result to a single variable 1 and testing its length:

t = do_something()
# t is now a tuple (or list, or whatever was returned) of results
if len(t) > 2:
    # Can use the third result!
    c = t[2]
Score: 2

So errors is a list that contains items that are 13 tuples of length 2 or 3. You want a way 12 to unpack tuples of varying length in a 11 for-loop. As you have noted, there is no 10 clean way to do this in Python2. Rather 9 than coming up with a clever way of implementing 8 this behavior, I would suggest making sure 7 that your errors list always contains tuples 6 of length of 3. This can be done every 5 time you add an item to errors, or after the fact, like 4 this:

errors = [(x[0], x[1], x[2]) if len(x) == 3 else (x[0], x[1], None) for x in errors]

Or you could make a generator (which 3 goes against my advice of not finding clever 2 way to implement this behavior):

def widen_tuples(iter, width, default=None):
    for item in iter:
        if len(item) < width:
            item = list(item)
            while len(item) < width:
                item.append(default)
            item = tuple(item)
        yield item

Use it like 1 this:

>>> errors = [(1, 2), (1, 2, 3)] 
>>> for a, b, c in widen_tuples(errors, 3):
...     print a, b, c
1 2 None
1 2 3
Score: 1

You could write a utility function to make 1 your results uniform:

def do_something2():
    return 1, 2

def do_something3():
    return 1, 2, 3

def do_something5():
    return 1, 2, 3, 4, 5

def uniform_result(*args):
    return args[0], args[1], args[2:]

a, b, c =  uniform_result(*do_something2())
print a, b, c
# 1 2 ()

a, b, c =  uniform_result(*do_something3())
print a, b, c
# 1 2 (3,)

a, b, c =  uniform_result(*do_something5())
print a, b, c
# 1 2 (3, 4, 5)
Score: 1

I suggest complementing the list to the 4 necessary length with the None elements:

data = give_me_list()
(val1, val2, val3) = data + (3 - len(data)) * [None]

3 is 3 the number of the left hand side values. If 2 the list can have excessive elements, then 1 use protection against that:

data = give_me_list()[:3]
(val1, val2, val3) = data + (3 - len(data)) * [None]

More Related questions