-2

I'm trying to return the student name and the sum of their points for the student with the highest total of points. I have my code below.

Code:

# student_grades contains scores (out of 100) for 5 assignments
student_grades = {
    'Andrew': [56, 79, 90, 22, 50],
    'Nisreen': [88, 62, 68, 75, 78],
    'Alan': [95, 88, 92, 85, 85],
    'Chang': [76, 88, 85, 82, 90],
    'Tricia': [99, 92, 95, 89, 99]
}

# calculate the top student and their total points
list_of_student_grades = list(student_grades.items())

top_student = tuple([(name, sum(grades)) for (name, grades) in list_of_student_grades if
                     sum(grades) == max([sum(grades) for name, grades in list_of_student_grades])])

print(list_of_student_grades)
print(top_student)

Output:

[('Andrew', [56, 79, 90, 22, 50]), ('Nisreen', [88, 62, 68, 75, 78]), ('Alan', [95, 88, 92, 85, 85]), ('Chang', [76, 88, 85, 82, 90]), ('Tricia', [99, 92, 95, 89, 99])]
(('Tricia', 474),)

I have two questions... First, why is the output not just ('Tricia', 474) (why the extra comma and set of parenthesis)? Second, is there a better way to go about this?

Thank you in advance!

  • `sum_of_points = [(k, sum(student_grades[k])) for k in student_grades.keys()]` This will return list of tuple where the first item will be student name and the next will be the sum of points. – Yoshikage Kira Jun 10 '21 at 20:25
  • *The one liner solution:* `tuple(map(lambda x: max(x.items(), key=lambda v:v[1]),[dict(zip(student_grades.keys(), map(sum,student_grades.values())))]))` gives output as `(('Tricia', 474),)` – ThePyGuy Jun 10 '21 at 20:32

1 Answers1

3

You created a list containing exactly one tuple, which when passed to tuple produces a tuple containing exactly one tuple.

All you really want is the maximum value of the list of name/sum pairs, with the maximum being defined as the pair with the largest sum.

>>> max([(name, sum(grades)) for name, grades in list_of_student_grades], key=lambda x: x[1])
('Tricia', 474)

A possible alternative is to simply compute the name of the student with the highest sum, then recompute their sum to build the desired tuple. Computing Tricia's grade twice is redundant, and I don't know if this looks any better, but I thought it was interesting enough to mention.

>>> def compute_sum(name):
...  return sum(student_grades[name])
...
>>> (name:=max(student_grades, key=compute_sum), compute_sum(name))
('Tricia', 474)
chepner
  • 497,756
  • 71
  • 530
  • 681
  • 1
    Returning the maximum is indeed better than returning the first item matching the condition that it is the maximum... – mkrieger1 Jun 10 '21 at 20:26
  • I was just typing this exact solution up and you beat me to it -- yes, the original implementation is a very roundabout way of reimplementing `max`. :) – Samwise Jun 10 '21 at 20:27