Python Homework - file i/o - read file and turn into dictionary
Question: I need to create a function that takes no arguments and reads back the
dictionary that is in a previously-saved file. I must first determine if the
file exists. If it does, I must read the contents of the file and return it as
a dictionary. If not, return `[]`.

I'm fairly new to Python and I've been brain dead looking at this for a couple
hours now. Any help would be much appreciated!

For example:

    
    
    dave 12
    brad 18
    stacy 8
    

This would now be read as `{'dave': 12, 'brad': 18, 'stacy': 8}`.

So far I have this:

    
    
    def readit():
    
        file1 = open('save.txt', 'r')
        data = []
        lines = file1.readlines()
        for i in range(len(lines)):
            data.append(lines[i].split('\n'))
        return data
        file1.close()
    


Answer: This'll do it:

    
    
    import os.path
    
    def readit():
        filename = 'save.txt'
        if not os.path.isfile(filename):
            return {}
        with open(filename) as ifh:
            return dict(line.split() for line in ifh)
    

This first tests if the file exists; if it does not an empty dictionary is
returned.

If there are spaces between the names, use `.rsplit(None, 1)`; this'll split
on the last whitespace within the line only:

    
    
    def readit():
        filename = 'save.txt'
        if not os.path.isfile(filename):
            return {}
        with open('save.txt') as ifh:
            return dict(line.rsplit(None, 1) for line in ifh)
    

which will turn:

    
    
    Martijn Pieters 42
    user3014014 38
    

into

    
    
    {'Martijn Pieters': '42', 'user3014014': '38'}
    

Note the `with` statement here also. This uses the file object as a context
manager, meaning that as soon as the block exits (using `return`, due to an
exception or simply because the block ends) then the file is automatically
closed for you. Your `file1.close()` line on the other hand will never be
executed as it is placed after the `return` statement.

The above, of course, gives us _strings_ for values. Lets expand this to
produce integer values instead:

    
    
    def readit():
        filename = 'save.txt'
        if not os.path.isfile(filename):
            return {}
        with open('save.txt') as ifh:
            return {key: int(value) for line in ifh for key, value in (line.rsplit(None, 1),)}
    

This produces:

    
    
    {'Martijn Pieters': 42, 'user3014014': 38}
    

for my sample input.

