Как насчет использования словаря для сбора предметов на каждого человека:
from collections import defaultdict
subjects = defaultdict(list)
for record in data_list:
subjects[record[0]].append(record[1])
# subjects
defaultdict(list,
{'John': ['Physics', 'PC', 'Math'],
'Mary': ['Physics', 'PC', 'Algebra'],
'Helen': ['Physics', 'PC', 'Algebra', 'Analysis'],
'Bill': ['PC', 'Analysis', 'Math', 'Biology'],
'Michael': ['Analysis']})
Затем его можно преобразовать в список списков:
subjects_list = [[x] + y for x, y in subjects.items()]
# subjects_list
[['John', 'Physics', 'PC', 'Math'],
['Mary', 'Physics', 'PC', 'Algebra'],
['Helen', 'Physics', 'PC', 'Algebra', 'Analysis'],
['Bill', 'PC', 'Analysis', 'Math', 'Biology'],
['Michael', 'Analysis']]
EDIT По запросу OP, вот решение, использующее только списки:
subject_list = [] # output
persons = [] # track unique persons
for record in data_list:
if record[0] not in persons:
persons.append(record[0]) # Track new person
subject_list.append([record[0]]) # Add new person to output
subject_list[-1].append(record[1]) # Add subject for person
else:
subject_list[persons.index(record[0])].append(record[1])
# subject_list
[['John', 'Physics', 'PC', 'Math'],
['Mary', 'Physics', 'PC', 'Algebra'],
['Helen', 'Physics', 'PC', 'Algebra', 'Analysis'],
['Bill', 'PC', 'Analysis', 'Math', 'Biology'],
['Michael', 'Analysis']]
EDIT 2 Вы можете обобщить этот подход, чтобы отсортировать ваши data_list
по любому индексу (например, человек, ...), отфильтровывая категорию (например, предмет, оценка, ...)
def groupby(data, index, category):
"""Sort list of records by index and category
"""
output = []
indices = []
for record in data:
if record[index] not in indices:
indices.append(record[index])
output.append([record[index]])
output[-1].append(record[category])
else:
output[indices.index(record[index])].append(record[category])
return output
Это позволит вы можете перечислить предметы для каждого человека следующим образом:
# index 0 -> person
# category 1 -> subject
subject_list = groupby(data_list, 0, 1)
Или вы можете указать оценки на человека следующим образом:
# index 0 -> person
# category 2 -> grade
grade_list = groupby(data_list, 0, 2)
# grad_list
[['John', 5, 7, 8],
['Mary', 6, 10, 7],
['Helen', 7, 6, 8, 10],
['Bill', 10, 6, 8, 6],
['Michael', 10]]
Затем вы можете получить количество предметов, взятых на каждого человека. человек или средняя оценка, например:
import statistics
subjects_taken = [len(x) - 1 for x in subject_list]
average_grade = [statistics.mean(x[1:]) for x in grade_list]
Если сложить все вместе, вы получите:
persons = [x[0] for x in subject_list]
final_list = list(zip(persons, subjects_taken, average_grade))
# final_list
[('John', 3, 6.666666666666667),
('Mary', 3, 7.666666666666667),
('Helen', 4, 7.75),
('Bill', 4, 7.5),
('Michael', 1, 10)]