[МУЗЫКА] Мы поговорили про основные операции с последовательностями, и сейчас мы поговорим про еще одну. Мы с вами должны решить каким-то образом задачу, как же нам наконец-то перебрать элементы в нашем списке, например, задачу вывода списка на экран без скобок, кавычек и прочей технической информации мы решили оператором распаковки. Мы печатали наш список, использовали звездочку, и функция print, например, понимала такой список как перечень элементов, как будто бы они все пришли к ней как отдельные аргументы. Но представьте, что нам не надо вывести список разом, а с каждым элементом сделать что-то отдельно. Например, здесь очень простой пример, давайте мы хотим написать, что мы хотим что-то купить и каждый элемент перечислим. У меня получилось пять строчек кода. Опять же этот код у меня был подготовлен заранее. Как раз потому что писать его долго и это выглядит не слишком удобно, согласитесь. Но я получила свой красивый вывод. Что я знаю? Что мне нужно купить хлеб, молоко, сметану и еще одно молоко. И естественно, если вы попробуете какой код написать даже для нашего маленького списка покупок, у вас это займет какое-то время. А что делать если список какой-то большой? Там может быть и 100 или даже больше элементов. Очевидно, нам нужен какой-то способ автоматически перебирать элементы в нашем списке. Давайте подумаем, как бы мы могли это сделать с помощью цикла while, с которым мы уже знакомы. Давайте мы зададим переменную i, в которой будем хранить 0. Мы будем эту переменную использовать для того, чтобы обратиться к элементу списка по индексу. Давайте, например, сейчас i равна нулю, и я печатаю shopping list [i], так, опечаталась, поправим. Хлеб. То есть, таким образом в переменной я храню некоторое значение индекса и могу по этому индексу обратиться к какому-то объекту внутри моего списка. А теперь давайте мы напишем цикл, который будет работать, пока i меньше длины списка. Теперь мы уже знаем, что с помощью функции len мы можем узнать количество элементов не только строки, но в том числе списка или кортежа. И таким образом мой цикл будет работать, пока i меньше длины списка. И таким образом, если внутри цикла я буду мою переменную i каждый раз увеличивать на один, я переберу все возможные индексы в моем списке. Итак, печатаю. Нам нужно купить двоеточие sh_list [i]. И не забываю увеличить i на 1. Соответственно, на первой итерации цикла у меня выведется хлеб, потом молоко и так далее, потом в какой-то момент i станет равна длине списка, и соответственно наш цикл остановится. Получилось. Но выглядит не очень удобно. Все еще. Потому что нам надо думать про вот эту вот переменную, про то, как обозначить это условие, про то, что надо не забыть обязательно i увеличить, иначе мы получим бесконечный цикл. И, как обычно, в Python, естественно, есть решение, которое делает всю эту историю гораздо более комфортный, чтобы ее использовать. У нас есть цикл, который обозначается кодовым словом for. И выглядит он вот так. Мы здесь пишем название какого-то элемента, переменной. И говорим, что для каждого объекта в какой-то последовательности здесь у нас список или кортеж, но дальше мы увидим, что и со строками, конечно же, работает. Дальше мы ставим двоеточие, как обычно, мы ставим, когда мы хотим какие-то инструкции выполнить, например, внутри условного оператора или внутри цикла. И вот здесь пишем действия. Давайте попробуем это воплотить. for thing in sh_list, наш любимый список покупок, он вам уже знаком. Давайте будем печатать. Удалю этот комментарий и вместо него напишу print (thing). То есть мы говорим циклу: «Пожалуйста, в нашем списке возьми каждый элемент и напечатай его». И действительно, вот у меня все напечаталось. Я могу здесь сделать мою красивую строку «нам нужно купить», но я думаю, понятно, что это будет работать. Давайте разбираться, как это работает. Вот это thing — это на самом деле название переменной. Оно может быть каким угодно, я могу x назвать, запустить этот цикл, и все все еще будет работать. Это название переменной, в которую Python кладет по очереди каждый объект списка, например, по очереди сначала туда попадает хлеб и печатается, и мы попали опять в начало списка. Поэтому он говорит: «Ага, а есть ли у меня другие элементы в моем списке?» Смотрит, говорит: молоко. И теперь в переменную x попадает молоко, и так далее, пока мы не доходим до конца. Давайте я обратно переименую ее на thing. Но еще раз: это просто название переменной, неважно, как вы ее назовете. И то есть где-то внутри этого цикла происходит операция, которую мы не видим, где вот этой переменной присваиваются следующие элементы списка, которые мы перебираем до конца, пока не закончатся элементы. И давайте убедимся, что это переменная существует и вне цикла. [ЗВУК] Давайте вот так напечатаю, чтобы не запутаться. Итак. В нашем цикле мы перебрали все элементы, и каждый из них по очереди попал в переменную thing, вот они все выведены. И потом вне цикла я печатала нашу переменную, она существует. Но обычно мы вне цикла этой переменной пользоваться не будем. То есть она отработала, мы выполнили какие-то действия с нашими элементами и теперь переходим к какой-то следующей части нашей программы обычно. Давайте посмотрим, у меня есть пример. Опять наш любимый список покупок. И мы печатаем здесь каждый из его элементов. И печатаем последнее значение этой переменной. А потом у меня новый список, и теперь это книжки, которые мы хотим купить. И теперь опять я перебираю все книги в нашем списке книг и печатаю их. И опять же, печатаю последнее значение переменной elem. elem — здесь сокращенно для «элемент». Обратите внимание, что и здесь, и здесь переменная называется одинаково. И, соответственно, что получилось? Сначала мы перебрали все значения этого списка, они печатались. И мы напечатали последнее значение этой переменной. А потом мы запустили новый цикл и используем там переменную с тем же названием. Но ничего страшного. Ведь уже на первой итерации цикла она перезаписалась. Туда попал «Белый клык», потом «Дубровский», потом «ОНО», и последнее значение этой переменной вот. Я уже сказала, что эту переменную мы обычно используем только внутри цикла, и потом она нам, по сути, не нужна. Поэтому ничего страшного, если вы пишете два цикла подряд и называете переменную одинаково, если вам логически кажется, что название такой переменной вам подходит и вы не хотите изобретать какое-то новое имя. Давайте сделаем еще такую задачу: давайте в цикле будем не только перебирать элементы, но и изменять, например, нумерацию. Давай теперь напечатаем наш список покупок пронумерованный. Опять создаю переменную i, которая равна единице. Буду считать для себя, я хочу выводить номера, поэтому мне не важно, чтобы она с нуля начиналась. Дальше буду запускать цикл for elem in sh_list и теперь я буду печатать не только этот элемент, но и его порядковый номер. И внутри цикла буду прибавлять единичку. То есть цикл for, как и цикл while, может работать с какими-то другими операциями, то есть не обязательно у нас все инструкции должны быть про элементы. То есть что здесь произошло? Мы перебрали все элементы, и каждый раз, когда мы попадали в этот цикл, мы еще увеличивали значение переменной i на один, чтобы у нас здесь получилась корректная нумерация. То есть когда мы попали в цикл, у нас i была равна единице, и в переменного elem у нас попал хлеб, и мы напечатали один хлеб. И прибавили к i один. Соответственно i теперь равно двум, возвращаемся в начало цикла, в elem теперь попадает следующий элемент списка. У нас это молоко. i теперь равно двум, печатаем два молоко и так далее, пока все не закончилось. Соответственно, давайте подытожим. Цикл for помогает нам перебирать элементы в последовательности. Мы посмотрели, как он работает со списком, но он будет работать и с кортежем, и со строкой. Внутри цикла for в отличие от цикла while создается переменная, куда попадают значения из нашего списка по очереди. И цикл работает таким образом, что он перебирает все элементы списка, пока они не закончатся, то есть каждый элемент в свою очередь попадет в эту переменную, и мы сможем внутри цикла выполнить с ним какие-то операции. [МУЗЫКА]