The problem: Given a list of student records, return a dictionary mapping each subject to the name of the student with the highest grade. No ties.
students = [
{'name':'Alice','grade':88,'subject':'math'},
{'name':'Bob','grade':72,'subject':'math'},
{'name':'Alice','grade':95,'subject':'science'},
{'name':'Bob','grade':81,'subject':'science'},
{'name':'Charlie','grade':90,'subject':'math'},
{'name':'Charlie','grade':78,'subject':'science'},
]my inital approach
My first instinct was to list the subjects upfront and scan through the students for each one. Reset the high score each time you move to a new subject, track the winner. (took a while to get it done.😭 am i getting rusty? no)
def top_student_per_subject(students):
subject = ['math','science']
nl = {}
for sub in subject:
hs = 0
for student in students:
name = student['name']
score = student['grade']
if student['subject'] == sub and score > hs:
hs = score
nl[sub] = name
return nlThis works (isn't that what matters?). But it has two problems I noticed after writing it🥲:
- The subjects are hardcoded. If someone adds
'history'to the data, the function silently ignores it. - It's O(subjects × students); a nested loop where a single pass would do.
def top_student_per_subjects(students):
result = {}
top_score = {}
for student in students:
sub = student['subject']
if sub not in top_score or student['grade'] > top_score[sub]:
top_score[sub] = student['grade']
result[sub] = student['name']
return resultOne pass. No hardcoded subjects. The sub not in best_score check handles the first encounter of any subject, no need to initialise with zero.
the thing worth remembering
The pattern here is "groupwise max." Whenever you see "for each category, find the best X," your instinct should be a single scan with a dictionary tracking the running winner per group. The nested-loop version isn't wrong, it's just the version you write before you see the pattern.