2
votes

Getting the below error while iterating tuples. I am not sure what changes do I need to apply to iterate. Any help would be appreciated.

ValueError: too many values to unpack (expected 3)

Program:-

 def convert_tuple_to_dict(self, tup):

        dt = defaultdict(list)
        temp_lst = []

        for i in range(len(tup)):

            if (len(tup[i]) == 2):
                for a, b in tup:
                    dt[a].append(b)

            if (len(tup[i]) == 3):
                print(tup[i])
                for (a, b, c) in tup[i]:
                    dt[a].append(b)
                    dt[a].append(c)

        return dict(dt)

    run = DataType()
    print(run.convert_tuple_to_dict(
        (('1328', '50434022', '53327'), (777, '5000435011607', '00720645'))))

Traceback details:-

Traceback (most recent call last):
  File "foo/DataType.py", line 95, in <module>
    print(run.convert_tuple_to_dict(
  File "foo/DataType.py", line 86, in convert_tuple_to_dict
    for (a, b, c) in tup[i]:
ValueError: too many values to unpack (expected 3)
('1328', '50434022', '53327')

Expected Output:

{'1328': ['50434022', '53327'], 777: ['5000435011607', '00720645']}
3
Can you print out tup at each iteration of the loop, to inspect what's going on? - clubby789
@JammyDodger Added print statement below if condition and you can see the printed message at the bottom of the traceback. - Learner
In the tuple (777, '5000435011607', '00720645') you actually need '777 ' ? - t_e_o
@t_e_o I have added the expected results. - Learner
from where did you learn this kind of for loop? for x,y,z in list? @Tester - taurus05

3 Answers

4
votes
       if (len(tup[i]) == 3):
            print(tup[i])
            for (a, b, c) in tup[i]:

Here you're checking the length of the tup[i] then iterating on it and trying to further unpack each item.

So given tup[i] = ('1328', '50434022', '53327') you're going to do:

a, b, c = '1328'
a, b, c = '50434022'
a, b, c = '53327'

which is unlikely to be what you're trying to do. The solution is to not iterate the tuple, just unpack-assign...

a, b, c = tup[i]
# do the thing

You have the same mistake in the 2-tuple case incidentally.

There's a few other debatable bits in your snippet:

  • tup is not a tuple at all, it's a sequence of inputs, so the naming is misleading
  • there's no point at which you need the index, so you've no reason to iterate on range(len(...)), just iterate the thing directly
  • you could use extended unpacking to not care about the length of the input tuples at all:
def convert_tuple_to_dict(self, in_tuples):
    dt = defaultdict(list)
    for key, *values in in_tuples:
        dt[key].extend(values)
    return dict(dt)
2
votes

The unpacking shouldn't be in a loop

if len(tup[i]) == 3:
    a, b, c = tup[i]
    dt[a].append(b)
    dt[a].append(c)

for x in tup[i] already unpack the tuple, which means you are trying to assign one value to 3 variables

a, b, c = `1328`

You also don't need all the checks, use slice to append all the values

def convert_tuple_to_dict(self, tup):

    dt = defaultdict(list)

    for i in range(len(tup)):
        dt[tup[i][0]].extend(tup[i][1:])

    return dict(dt)
1
votes

If your tuple is of the format [(x1,y1,z1),(x2,y2,z2),(x3,y3,z3), ... ,(xn,yn,zn)] You can go something like this:

for x,y,z in my_tuple:
        '''
        Rest of the code goes here -- it can loop over each element of the list of tuples
        And unpack each element of the tuple in the form of x,y,z
        '''