Как найти среднее арифметического словаря python через добавление нового ключа
Выполнял задание по словарям в python, решил сверх добавить вывод самого среднего арифметического через добавление нового ключа avg в полученный словарь best_students
Само задание: Есть список словарей со студентами students. В каждом объекте есть имя и фамилия студента, а также список оценок (целых чисел). Нужно написать функцию get_best_students, которая берёт студентов и находит того, у кого средний балл наибольший.
Возвращает функция список студентов с лучшим баллом best_students
students = [
{"name": "John", "surname": "Doe", "grades": [5, 5, 4, 4]},
{"name": "Jane", "surname": "Doe", "grades": [4, 3, 4, 3, 5]},
{"name": "Bill", "surname": "Gates", "grades": [5, 5, 5, 3]},
{"name": "Steve", "surname": "Jobs", "grades": [3, 5, 4, 3, 3, 5]},
{"name": "Guido", "surname": "Van Rossum", "grades": [5, 3, 5, 4, 5, 5, 3, 5]},
{"name": "Elon", "surname": "Musk", "grades": None} ]
Код решения:
def get_best_students(*, students: list[dict]) -> list[dict]:
best_students = []
best_average_grade = 0
for student in students:
grades = student["grades"]
if grades is None:
average_grade = 0
else:
average_grade = sum(grades) / len(grades)
if average_grade > best_average_grade:
best_average_grade = average_grade
best_students = [student]
elif average_grade == best_average_grade:
best_students.append(student)
best_students.append('avg') # Мой созданный ключ avg
return best_students
print(get_best_students(students=students)) # Outputs [{'name': 'John', 'surname': 'Doe', 'grades': [5, 5, 4, 4]}, {'name': 'Bill', 'surname': 'Gates', 'grades': [5, 5, 5, 3]}, 'avg']
Я смог добавить новый ключ avg в словарь best_students, но не могу понять, как передать ему переменную avg_grades, чтобы вывести ср. арифметическое оценок в best_students
Также при попытке добавить такую строку: best_students['avg'] = avg_grade выдаёт ошибку TypeError: list indices must be integers or slices, not str
Изменение скобок не даёт результата: cannot assign to function call here. Maybe you meant '==' instead of '='? или же 'list' object is not callable. Может нужна новая функция? Как это всё связать..
Ответы (2 шт):
best_students - это список (list), который изначально содержит словари студентов
.append() - метод списка, который добавляет новый элемент в конец списка
'avg' - это строка (string), а не ключ словаря
Результат выполнения этой (best_students.append('avg')) строки:
До выполнения:
best_students = [{'name': 'John', 'surname': 'Doe', 'grades': [5,5,4,4]}]
После выполнения:
best_students = [
{'name': 'John', 'surname': 'Doe', 'grades': [5,5,4,4]},
'avg' # ← это строка, а не словарь и не ключ!
]
вот решение которое я предлагаю:
def get_best_students(*, students: list[dict]) -> list[dict]:
best_students = []
best_average_grade = 0
for student in students:
grades = student["grades"]
if grades is None:
average_grade = 0
else:
average_grade = sum(grades) / len(grades)
# Добавляем средний балл как ключ в словарь студента (опционально)
student_with_avg = student.copy()
student_with_avg['avg'] = round(average_grade, 2)
if average_grade > best_average_grade:
best_average_grade = average_grade
best_students = [student_with_avg]
elif average_grade == best_average_grade:
best_students.append(student_with_avg)
return best_students
students = [
{"name": "John", "surname": "Doe", "grades": [5, 5, 4, 4]},
{"name": "Jane", "surname": "Doe", "grades": [4, 3, 4, 3, 5]},
{"name": "Bill", "surname": "Gates", "grades": [5, 5, 5, 3]},
{"name": "Steve", "surname": "Jobs", "grades": [3, 5, 4, 3, 3, 5]},
{"name": "Guido", "surname": "Van Rossum", "grades": [5, 3, 5, 4, 5, 5, 3, 5]},
{"name": "Elon", "surname": "Musk", "grades": None}
]
result = get_best_students(students=students)
print(result)
Так то никто вам не запрещает возвращать из функции кортеж из максимального среднего и списка студентов. Ну и код можно гораздо короче написать, используя списковые сокращения:
def avg(lst):
return 0 if lst is None else sum(lst)/len(lst)
def get_best_students(*, students: list[dict]) -> tuple[float, list[dict]]:
max_avg = max(avg(s['grades']) for s in students)
return max_avg, [s for s in students if avg(s['grades']) == max_avg]
print(*get_best_students(students=students), sep='\n')
# 4.5
# [{'name': 'John', 'surname': 'Doe', 'grades': [5, 5, 4, 4]}, {'name': 'Bill', 'surname': 'Gates', 'grades': [5, 5, 5, 3]}]
И вам уже объяснили, что список и словарь - это разное, в список нельзя добавлять элементы по ключу, это функция словаря.