Josh Friedman
Josh Friedman

Reputation: 69

Dictionaries and files in python

Hey guys first time question here.

I'm trying to figure out how to create a dictionary containing keys as ID's, and values as another dictionary containing scores for homework essays and exam's for that individuals ID.

Example:

{"173-25-6389":
    {
        "hw":[94,89,92,73], 
        "quiz":[45,36,42,50,22,27,40,41], 
        "exam":[135,127]
    },
.....
}

These numbers are being pulled from separate files representing the categories and are each matched with their corresponding ID.

I have 4 files to work with and one of them just contains the IDs which I think I will apply to the keys in the larger dictionary.

My main issue is that inside of the files, each line is written like:

173-25-6389 61

So it's the id plus a space and then the score. I'm not sure how to run through the file and search for the other scores that have the same ID.

I'm just a bit confused as to how to find a list of the scores, and then add that to a dictionary as the value for the larger dictionary containing the ID's. Any insight as to how to precede would really be amazing and if you need me to elaborate more let me know.

I have only been coding for about a year so go easy on me. Thanks

Upvotes: 2

Views: 164

Answers (2)

Josh Friedman
Josh Friedman

Reputation: 69

I figured it out. I bet there is a much neater way to write it maybe even using some form of recursion im just not experienced enough yet to figure it out. But this is what I got and it returns me what I need. Thanks for the help!

def create_dictionary(idfilename,hwfilename,qzfilename,examfilename):
idread = open(idfilename, 'r')
hwread = open(hwfilename, 'r')
qzread = open(qzfilename, 'r')
examread = open(examfilename, 'r')
dict = {}
dicthw = {}
dictqz = {}
dictexam = {}

for line in idread:
    if line not in dict:
        dict[line.rstrip('\n')] = {}
for line in hwread:
    name, score = line.split()
    if name in dicthw:
        dicthw[name].append(score)
    else:
        dicthw[name] = [score]
for line in qzread:
    name, score = line.split()
    if name in dictqz:
        dictqz[name].append(score)
    else:
        dictqz[name] = [score]
for line in examread:
    name, score = line.split()
    if name in dictexam:
        dictexam[name].append(score)
    else:
        dictexam[name] = [score]
for k, v in dicthw.items():
    if len(v) < 4:
        while len(v) < 4:
            v.append(0)
    if k in dict:
        dict[k] = ({'hw':v})
for k, v in dictqz.items():
    if len(v) < 8:
        while len(v) < 8:
            v.append(0)
    if k in dict:
        qz_update = {'qz':v}
        dict[k].update(qz_update)
for k, v in dictexam.items():
    if len(v) < 2:
        while len(v) < 2:
            v.append(0)
    if k in dict:
        exam_update = {'exam':v}
        dict[k].update(exam_update)
return(dict)

Upvotes: 0

kojiro
kojiro

Reputation: 77167

So let's assume you already know how to open the file and read it line-by-line. For each line you have an id and a score, but you don't know if the score already exists in your result dict. Frankly, you'd rather not care. Enter defaultdict. It guarantees you a useful value even if the particular key doesn't exist.

from collections import defaultdict
…
result = defaultdict(dict) # an undefined key will map an empty dict
for line in scorefile:
    id, score = line.split()
    result[id]['hw'] = score

But wait, that will overwrite our 'hw' key with a single score! We wanted a list!

Let's double down on this defaultdict.

# an undefined key will map a defaultdict
# whose undefined keys will map an empty list
result = defaultdict(lambda: defaultdict(list))
for line in scorefile:
    id, score = line.split()
    result[id]['hw'].append(score)

Now, you didn't say how we were to tell homework from exam scores, so I'll leave that bit up to you…

Upvotes: 3

Related Questions