Вложенные списки — достаточно сложная тема. Поэтому давайте решим еще одну задачку, чтобы побольше потренироваться. Задачка у нас будет интерактивная. Будем искать итоговую оценку за предмет. Предположим, что мы спрашиваем у пользователя с какими предметами мы будем работать. Так мы узнаем их названия и их количество. Потом для каждого предмета мы пользователя попросим ввести те оценки, которые он, например, получил на данный момент или, в принципе, получил за прошедший модуль или семестр. Логично такую структуру хранить в списке списков. У нас оценки за каждый курс будут списком, которые хранятся в большом списке, который хранит списки всех оценок за все предметы. И потом, когда мы все это считаем, а задача уже даже на этом этапе непростая, мы пройдемся по этой вложенный структуре с помощью цикла, чтобы посчитать для каждого курса итоговую оценку, а потом ее выведем. Давайте есть слона по частям, начнем сначала. Прежде всего нам надо узнать с каким количеством предметов мы работаем и как они называются. Это нам тоже потом пригодится в конце для вывода. Мы будем считывать названия предметов в список и в строке мы будем названия предметов разделять запятой. Буду сохранять их в переменной "courses (input)". Давайте оформим хорошо. "Введите названия предметов". Можно тут даже дать подсказку пользователю, что мы хотим через запятую. Подсказать, что мы ожидаем. И я прямо здесь хочу хранить их в списке, прямо здесь введенную строку буду разбивать с помощью метода "split()", используя разделитель запятая. Чуть-чуть не вошел код. Вот он. Итак, запускаем. Давайте будем работать с такими предметами как "сольфеджио" и "карате". Давайте проверим, что все корректно считалось. У нас получился список из двух предметов. Теперь нам для каждого из них нужно считать оценки. Как я уже сказала, мы будем создавать список списков, поэтому давайте создадим список, в котором будем хранить все оценки. Пусть он будет пока пустым. "marks_all". Теперь нам каким-то образом нужно считать для каждого из моих двух предметов оценки. Итак, у меня есть два предмета, мне надо два раза запустить ввод. Тут самое логичное решение — запустить либо "while", либо цикл "for i in range", чтобы он выполнился заданное количество раз. И давайте здесь подсказывать пользователю, с каким предметом мы работаем. Давайте запустим. Да, то есть, соответственно, цикл у меня прошел два раза. Первый раз напечатал, что предмет с которым мы работаем — это сольфеджио, и второй раз — карате. Теперь давайте мы попросим пользователя вводить нам оценки. Давайте назовем это "course_marks input('Введите оценки через пробел')". Мы предполагаем, что оценки могут быть вещественными числами, например, 9 и 4. Тут сильно длинно писать. Предположим, что пользователь и так это знает. И я сразу же разбиваю. Здесь я разделитель не указываю, потому что меня как раз устраивает разбивка по пробелам. Давайте посмотрим, что мы получим на этом этапе. Давайте я вот здесь поставлю еще break, где сольфеджио. Предположим: 6 8 9 и 5. Итак, получили логично список строк. Да? Потому что мы просто разбили, но дальше нам с этими строками надо работать как с числами. Потому что мы хотим найти среднюю оценку. Получается, что нужно их сначала перевести. Мы умеем применять с помощью функции "map()" какие-то функции к элементам списка. Здесь я хочу как раз применить функцию "float" — перевод в вещественное число ко всем элементам списка "course_marks". И, так как "map" возвращает нам объект своего какого-то хитрого типа, я еще перевожу это вот здесь обратно в список. Давайте еще раз прочитаем эту конструкцию. "Возьми функцию float, примени ко всем элементам в этом списке. И потом, когда у тебя получится по сути список из десятичных дробей, преврати вот этот получившийся объект в список". Давайте посмотрим, что сработало. Видите? Я перезаписываю переменную. Я удаляю список строк и перезаписываю его списком вещественных чисел. Работаем с предметом сольфеджио. Да, сработало. Теперь у меня "course_marks" — это список дробей. Последний пункт. Я хочу эту все добавить в мой список со всеми оценками "marks_all.append(course_marks)". Я вот в этом списке буду хранить списки оценок для каждого предмета. Я, в принципе, уверена, что все правильно, удалила принты, с помощью которых я смотрела, что мои инструкции работают корректно, что моя программа правильно написана и делают то, что я хочу. И удаляю break. Я на одном проходе по циклу убедилась, что все хорошо работает, теперь готова запускать его для всех. Итак, предмет сольфеджио. Вводим оценки. Оценок может быть какое-угодно количество, мы здесь не ставим ограничения, то есть, главное, чтобы это были какие-то корректные числа, которые потом переведутся в вещественную дробь. Теперь мы работаем со следующим предметом. Мы получили напоминание и мы вводим оценки для него. Вызывали вот здесь что-то, 10, давайте еще какое-нибудь вещественные число. Так, сработало. Я сейчас список мой итоговый, чтобы проверить, что получилось выведу в другой ячейке, чтобы у меня опять заново не запустился ввод и мне не пришлось это заново вводить. Вот у меня получился список оценок за два предмета. Мы ввели два предмета вот на этом этапе. Соответственно, мы ввели два предмета. Для каждого предмета считали список оценок и добавили в наш список "marks_all". Теперь осталось найти как раз для каждого предмета итоговую оценку. Давайте вот здесь я его тоже напечатаю, чтобы он перед глазами был. И запускаю цикл. Опять запускаю цикл по "i, for i in range". Почему? Потому что я хочу еще обращаться к названию предмета, чтобы в итоге вывести это: "Оценка по сольфеджио столько-то". "for i in range" — тут любой список, потому что "marks_all" у меня содержит два элемента, потому что у нас два предмета с которыми мы работаем, и "courses" у меня тоже содержит два названия предметов. "marks_all". Считаем среднюю оценку. "mark_average". Здесь воспользуемся функциями, которые работают со списками. Просуммируем. Так как у нас это список вещественных чисел, с ним будет работать функция "sum()". Просуммируем все элементы и, чтобы найти среднее арифметическое, нам надо все сложить и разделить на количество элементов. Количество элементов мы тоже умеем находить — это функция "len()". Тут достаточно все удобно. "marks_all". Только у меня здесь ошибка. Ведь мне нужно обратиться по индексу к нужному предмету, а не ко всему списку. И я еще привожу это к "int". У нас преподаватели строгие, поэтому оценка у нас не округляется, а просто отбрасывается дробная часть. Например, если вы получили 7.6, извините, но итоговое семь. Давайте печатать название элемента. Красиво это выведем: "Оценка за предмет под индексом i", то есть мы здесь цикл запустили "for i in range", чтобы мы смогли обратиться к нашим предметам, которые у нас хранятся в списке "courses", который мы считали в самом начале. "print(courses), print(marks_all)". Наши два списка с которыми мы работаем. И это у нас список, давайте это отсюда удалю, список названий предметов, список оценок по этим предметам. Тоже они соответствуют друг другу. Мы такие задачи решать умеем. Оценка за предмет, двоеточие, и вот здесь подставляю значение "mark_average". Не забываю закрыть кавычку. Вот, и там, и там у нас получилось восемь. Итоговая оценка. Мы их красиво вывели. Итак, мы посмотрели с вами как решать сложную задачу, как считывать элементы в список, создавать вложенную структуру и еще раз посмотрели, как проходиться по такому вложенному списку с помощью цикла, обращаться к элементам и проводить с ними какие-то операции.