How to create a Python dictionary from data imported from a text file?

Viewed 75

I have the following text in a file named my_text.txt:

David: 2
Barbara: 97.2
David: nothing
William:

Lynn: 725
Nancy   : 87
     David:       54
Lewis: 18.30
Sue:   3193.74
James: 41.73

David: 974.1

I would like to be able to read this file and create a dictionary.

Here is my code:

def make_dictionary(file_name):

    d = {}

    with open(file_name, 'r') as file:
        for line in file:
            (key, val) = (line.split(':')[0], line.split(':')[1])

    return print(d)

make_dictionary('my_text.txt')

I'm getting an index error:

IndexError: list index out of range

Does anyone see where the mistake is?

Thanks!

3 Answers

This error arises due to the blank lines.

Your code assumes the split will return two elements for you.

You'll want to check for blank lines before trying to use the return value of the split -- and skip those lines.

Also, more robust code would also check that the line contains a colon (:) on which to split on. If the line contains no colon, the code would fail. You may want to raise an exception in such a case, or at least print an error warning perhaps. You'll also need to use strip in order to remove extraneous whitespaces.

Your code also didn't assign to the dictionary -- so I've added that in as well. Also note -- print returns None, so where you had return print(d), it would return None. You'll want to return d, so I've updated that as well.

There's one last thing. You probably want to convert the second column of data into floats that can be used as numbers within Python, rather than the strings they would be when read from the file. In doing so, invalid lines would also raise an exception -- or perhaps you want to want to catch that and handle it differently.

Try the following:

def make_dictionary(file_name):
    d = {}
    with open(file_name, 'r') as file:
        for line in file:
            line = line.strip()
            if line == '':
                # Skip blank lines
                continue
            elif ':' in line:
                # Do the split, since we *know* we can
                key, val = line.split(':')

                # Will raise an exception if the 2nd column is not a valid number
                d[key.strip()] = float(val.strip())
            else:
                # Raise an exception if an invalid line is encountered
                raise ValueError('Cannot split line')
            
    return d

print(make_dictionary('my_text.txt'))

Note: Your original code split the line twice (which is inefficient and unnecessary). In Python, you can do parallel assignment instead (better known as "unpacking") -- I've adapted the code to use that approach.

If you want to make a dictionary, you should use a .json file. These were made for storing dictionary like objects.

Your William key has no value.
And you have a couple of empty lines.
So, before you split the line, check if it isn't empty, and after you split check if it's length is 2.
And, you need to assign something to d in order to return it, e.g.:

d[key] = value
Related