Reputation: 21
I have this text file:
English
hello bye
italian
ciao hola
spanish
hola chao
I want to create a dictionary from each 2 consecutive lines:
{
'English': 'hello bye',
'italian': 'ciao hola',
'spanish': 'hola chao',
}
Here's my code:
d= {}
with open("test.txt", 'r') as f:
l = f.readlines()
for line in l:
(key,val) = line.split()
d[key]=val
I get the error:
too many values to unpack error
Upvotes: 1
Views: 112
Reputation: 1907
i = 0
d = {}
prev_key = None
for line in l:
if i % 2 == 0:
prev_key = line
else:
d[prev_key] = line
i += 1
Upvotes: 1
Reputation: 20490
In your original code, you are reading all lines in the file in one go using f.readlines()
and then you are splitting each line. The problem is that not each line is giving you a list with two elements, so key, val = line.split()
gives you a values to unpack
, since you are trying to assign a single element list to two items. e.g a,b = [2]
which will result in this error like so.
In [66]: a,b = [2]
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-66-f9f79b7d1d3c> in <module>
----> 1 a,b = [2]
ValueError: not enough values to unpack (expected 2, got 1)
To avoid it, we just iterate through the lines we read, and every even element is a key and every odd element is a value in the dictionary.
dct = {}
with open("file.txt", 'r') as f:
l = f.readlines()
idx = 0
while idx < len(l):
#Even element is key, Odd element is value
key = l[idx].strip()
value = l[idx+1].strip()
dct[key] = value
idx+=2
#{'English': 'hello bye', 'italian': 'ciao hola', 'spanish': 'hola chao'}
Or a more terse solution using dict-comprehension is
l = []
with open("file.txt", 'r') as f:
l = f.readlines()
#This will be a list of tuples, with the first element of tuple being the key #and second value being the value
#Keys are obtained by slicing all even indexes, and values by slicing all odd indexes
key_value_tups = zip(l[::2], l[1::2])
#[('English \n', 'hello bye \n'), ('italian \n', 'ciao hola\n'), ('spanish\n', 'hola chao\n')]
#Iterate through the tuples and create the dict via dict-comprehension
dct = {key.strip() : value.strip() for key, value in key_value_tups}
print(dct)
#{'English': 'hello bye', 'italian': 'ciao hola', 'spanish': 'hola chao'}
Upvotes: 1
Reputation: 2084
You can do it in a single line :
with open("test.txt", 'r') as f:
lines = f.readlines()
dict( zip( lines[::2], lines[1::2] ) )
lines[::2]
will give you all the elements of lines
that have an even indexlines[1::2]
will give you all the elements of lines
that have an odd index
zip
will create an iterator (list1 elem, list2 elem)
from the two lists
dict
will take each tuple (key, value)
from the iterator as a dictionary item and create a dictionary
That one line is the equivalent of :
keys = []
values = []
for index, elem in enumerate(lines):
if index % 2 == 0:
keys += [elem]
else:
values += [elem]
d = {}
for key, val in zip(keys, values):
d[key] = val
Upvotes: 0
Reputation: 1493
You can also use this approach:
d = {}
with open("test.txt", 'r') as f:
l = f.readlines()
i = 0
while i < len(l):
d[l[i].replace("\n","")] = l[i+1].replace("\n","")
i += 2
Upvotes: 1
Reputation: 26039
Use a dictionary-comprehension using zip()
:
with open("test.txt", 'r') as f:
l = f.readlines()
d = {x: y for x, y in zip(l[::2], l[1::2])}
Upvotes: -1