Reputation: 161
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
Reputation: 141810
You have empty line
s in your input file and I suspect one of the line
s 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
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
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