Нужна помощь со вложенными списками (python)
Существует список студентов и их любимый предмет, и есть сам список предметов. Нужно узнать самый любимый предмет студентов (посчитать сколько раз встречается предмет и вывести предмет который встретился больше раз)
subject_list = ["Biology","Math","Geography ","Physics","English"]
students_list = [ ["Mike", "English"], ["Leana", "Biology"], ["Oleg", "Math"], ["Ivan", "Biology"], ["Mikola", "Math"], ["Hanna", "Biology"], ["Lena", "Geography"], ["Nick", "Physics"] ]
Ответы (2 шт):
Используйте класс Counter, который подсчитает частоту элементов списка:
from collections import Counter
favorite_subject_list = [element[1] for element in students_list]
favorite_subject = Counter(favorite_subject_list).most_common(1)[0][0]
Объяснение:
In[1]: [element[1] for element in students_list]
Читайте это выражение (так называемое «генератор списка») справа влево:
«Для всякого элемента element из списка students_list выбери element[1], т.е. второй член пары.»
(Элементами вашего списка являются пары, например первым элементом пара ["Mike", "English"].)
Таким образом вы получите
['English', 'Biology', 'Math', 'Biology', 'Math', 'Biology', 'Geography', 'Physics']
Теперь будем постепенно конструировать выражение во второй команде, добавляя в каждом шаге что-то за конец предыдущего:
In[2]: Counter(favorite_subject_list)
Counter({'English': 1, 'Biology': 3, 'Math': 2, 'Geography': 1, 'Physics': 1})
Мы получили объект типа Counter, который сохраняет элементы вашего списка вместе с их частотами.
Теперь применим метод .most_common(), который выберет из этого объекта определенное количество пар со самыми большими числами частот. Мы хотим только одну пару (т.е. пару со самой большой частотой), потому как параметр задаем число 1:
In[3]: Counter(favorite_subject_list).most_common(1)
[('Biology', 3)]
Это список (хотя только с одним элементом — кортежей) - выберем его первый (единый) элемент, т.е. элемент с индексом 0:
In[4]: Counter(favorite_subject_list).most_common(1)[0]
('Biology', 3)
и с полученной кортежи опять элемент с индексом 0:
In[5]: Counter(favorite_subject_list).most_common(1)[0][0]
'Biology'
from collections import defaultdict
frequencies = defaultdict(int)
for __, subject in students_list:
frequencies[subject] += 1
max_frequency = max(frequencies.values())
for subject in frequencies:
if frequencies[subject] == max_frequency:
print(subject)
break
Этот код выводит только один самый любимый предмет. Когда вы хотите вывести все самые любимые предметы (т.к. может быть несколько таких), уберите команду break.
Преимущество defaultdict() в том, что не надо тестировать, если ключ в словаре уже существует — когда не существует, полагается, что его значением есть стандартное значение (default). Для defaultdict(int) стандартным значением нуль (0).
Добавление: Без defaultdict — некрасиво, но когда вы так хотите...
frequencies = {} # Пустой словарь
for __, subject in students_list:
if subject in frequencies:
frequencies[subject] += 1
else:
frequencies[subject] = 0
max_frequency = max(frequencies.values())
for subject in frequencies:
if frequencies[subject] == max_frequency:
print(subject)
break
(Разница только в первой части, до max_frequency = ... )