Joe Nicklas
Joe Nicklas

Reputation: 21

Dictionary from text file

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

Answers (5)

vb_rises
vb_rises

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

Devesh Kumar Singh
Devesh Kumar Singh

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

Mohamed Benkedadra
Mohamed Benkedadra

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 index
  • lines[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

YusufUMS
YusufUMS

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

Austin
Austin

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

Related Questions