2

I have an txt file listing name and age:

John,20
Mary,14
Kevin,60
Mary,15
John,40

And trying to write the below function to return a dictionary:

def read(filename):
    results = {}
    with open(os.path.join(os.path.dirname(__file__), 'data.txt')) as file:
        for line in file:
            location,value = line.split(',', 1)
            results[location] = value
        print(results)

I'm trying to format as:

{'John': [20, 40], 'Mary': [14, 15], 'Kevin': [60]}

But currently getting:

{'John': '20', 'Mary': '15\n', 'Kevin': '60\n'}

Can anyone help me understand what I'm doing wrong?

r0llie
  • 69
  • 4
  • instead of this line `results[location] = value` you need to put if statment, and check whether location key already exists. if yes, append new value. if not `results[location] = [value]` – AmirA May 24 '20 at 08:56

2 Answers2

2

You need to test if the key is in the dictionary, if not add an empty list. Add the current value to the list at the key:

def read(filename):
    results = {}
    with open(os.path.join(os.path.dirname(__file__), 'data.txt')) as file:
        for line in file:
            if line.strip():     # guard against empty lines
                location,value = line.strip().split(',', 1)  # get rid of \n
                if location not in results:
                    results[location] = []
                results[location].append( int(value) )  # as number
        print(results)

You can lookup dict.setdefault(key,defaultvalue) and collections.defaultdict to get more performance if needed - f.e. here: How does collections.defaultdict work?

Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
1

You can try defaultdict:

from collections import defaultdict

def read(filename):
results = deafultdict(list)
with open(os.path.join(os.path.dirname(__file__), 'data.txt')) as file:
    for line in file:
        location,value = line.split(',', 1)
        results[location].append(value.replace("\n", ""))

You will get:

defaultdict(<class 'list'>, {'John': ['20', '40'], 'Mary': ['14', '15'], 'Kevin': ['60']})