I have been trying to create a program which the teacher log in to view the scores of a test of a school class. The scores are stored in a text file like this:

Charlotte:7
Charlotte:4
Charlotte:3
Chelsea:2
Chelsea:9
Chelsea:5
Jeff:1
Jeff:10

As you can see there are multiple scores for each student, I need to be able to sort these scores by highest score out of the class with each student's highest score. I've worked out how to sort it by each student's highest score with the following code but I now need to sort those highest scores of the students into the highest to lowest scored in the class.

import operator
import collections


d = collections.defaultdict(lambda: collections.deque(maxlen=3))

with open("class {0}.txt".format(Class)) as f:
#these lines adds the text file into the dictionary
    for line in f:
        name,score = line.strip().split(":")
        d[name].append(score)
#The next lines gets each students highest score
    for k in d:
        high = max(d[k])
        k + " " + " ".join(map(str, high))

The error is in the following lines, where i've tried to sort the list of 'high scores' into highest to lowest

        print(sorted(high, reverse=True))

It currently prints out this:

['7']

I have worked out how to sort it by each student's highest score but I am stuck on how to sort each highest score into highest to lowest.

Could someone give me some pointers or help on how I could sort the list and print it out like this..

Jeff 10
Chelsea 9
Charlotte 7

Thanks!

Edited 1 Year Ago by psvmr

Consider the following example from Click Here

>>> from operator import itemgetter, attrgetter, methodcaller

>>> sorted(student_tuples, key=itemgetter(2))
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

>>> sorted(student_objects, key=attrgetter('age'))
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

you can do the same with Reversed=True will sort it opposite order

Edited 1 Year Ago by Slavi

Oh, forgot to mention that this

>>> sorted(student_tuples, key=itemgetter(2))
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

they are sorting with key=itemgetter(2), I assume your sorting should be itemgetter(1)

Change last part to this.

lst = []
for k in d:
    high = int(max(d[k]))
    lst.append((k, high))

score_lst = sorted(lst, key=lambda tup: tup[1], reverse=True)
for name,score in score_lst:
    print('{} {}'.format(name, score))

It's ok to throw away lambda,and use itemgetter as shown by slavi.

Edited 1 Year Ago by snippsat

omg, thank you so much snippsat and slavi, been trying to figure it out for ages, Thank you!!

This might be a less complicated approach ...

import collections as co

# assume this is a string read from a file
# showing name:score data on each line
data_str = '''\
Charlotte:7
Charlotte:4
Charlotte:3
Chelsea:2
Chelsea:9
Chelsea:5
Jeff:1
Jeff:10'''

# convert to a name:score_list default-dictionary
ddict = co.defaultdict(list)
for line in data_str.split():
    name, score = line.split(':')
    ddict[name].append(int(score))

print(ddict)  # test

''' result ...
defaultdict(<class 'list'>, {'Charlotte': [7, 4, 3], 'Jeff': [1, 10],
'Chelsea': [2, 9, 5]})
'''

# create a list of (max_score, name) tuples
max_scores = [(max(scores), name) for name, scores in ddict.items()]

print(max_scores)  # test

''' result ...
[(7, 'Charlotte'), (10, 'Jeff'), (9, 'Chelsea')]
'''

# show result sorted by maximum score, high score first
for mscore, name in sorted(max_scores, reverse=True):
    print("{:10s} {}".format(name, mscore))

''' result ...
Jeff       10
Chelsea    9
Charlotte  7
'''
This question has already been answered. Start a new discussion instead.