Poker Face
Poker Face

Reputation: 161

How can I fix ValueError: Too many values to unpack" in Python?

I am trying to populate a dictionary with the contents of my text file ("out3.txt").

My text file is of the form:

vs,14100

mln,11491

the,7973

cts,7757

...and so on...

I want my dictionary answer to be of the form:

answer[vs]=14100

answer[mln]=11491

...and so on...

My code is:

import os
import collections
import re
from collections import defaultdict

answer = {}
answer=collections.defaultdict(list)
with open('out3.txt', 'r+') as istream:
    for line in istream.readlines():
        k,v = line.strip().split(',')
        answer[k.strip()].append( v.strip())

But, I get:

ValueError: too many values to unpack

How can I fix this?

Upvotes: 11

Views: 65505

Answers (3)

johnsyweb
johnsyweb

Reputation: 141810

You have empty lines in your input file and I suspect one of the lines that you have not shared with us has too many commas in it (hence "too many values to unpack").

You can protect against this, like so:

import collections

answer = collections.defaultdict(list)
with open('out3.txt', 'r+') as istream:
    for line in istream:
        line = line.strip()
        try:
            k, v = line.split(',', 1)
            answer[k.strip()].append(v.strip())
        except ValueError:
            print('Ignoring: malformed line: "{}"'.format(line))

print(answer)

Note: By passing 1 into str.split(), everything after the first comma will be assigned to v; if this is not desired behaviour and you'd prefer these lines to be rejected, you can remove this argument.

Upvotes: 12

Burhan Khalid
Burhan Khalid

Reputation: 174624

Your solution doesn't give your desired output. You'll have (assuming it worked), answer['vs'] = [14100], the below does what you intended:

import csv

with open('out3.txt') as f:
  reader = csv.reader(f, delimiter=',')
  answer = {line[0].strip():line[1].strip() for line in reader if line}

Upvotes: 4

pepr
pepr

Reputation: 20760

You do not need the collections here. Plain old dict is enough:

answer = {}
with open('out3.txt', 'r+') as f:
    for line in f:
        lst = line.split(',')
        if len(lst) == 2:
            k = lst[0].strip()
            v = lst[1].strip()
            answer[k] = v

print(answer['mln'])
print(answer.get('xxx', 'not available'))

Notice the answer.get() is similar to answer[] but you can supply the defaul value.

You should not use .readlines() in the loop. Even the empty line contains the newline character. This way the test if line: does not detects the empty lines. Or you have to strip (or rstrip) it first, or you can split the line to the list and test the number of elements.

Upvotes: 2

Related Questions