Ни одна
сколь-нибудь серьезная программа на Python не обходится без
циклов. Что такое циклы?
Представьте, что спортсмен бегает по
дорожкам стадиона и решил: пока не прошел один час, он бежит. То есть, пока
выполняется условие (оно истинно – не прошел час), циклично выполняются некие
действия – бегун бежит. Вот такую операцию на уровне языка Python выполняет
оператор цикла while, имеющий следующий синтаксис:
Смотрите как в Python записывается
группа операторов (тело цикла): вся группа должна иметь один и тот же сдвиг
относительно оператора while (обычно ставят четыре пробела или
символ табуляции). Причем такой отступ строго обязателен – это элемент
синтаксиса python. И благодаря этому
текст программы становится наглядным и хорошо читаемым. Это, безусловно, один
из плюсов данного языка.
Однократное выполнение тела цикла
называется итерацией. То есть, может быть первая итерация, вторая
итерация, N-я итерация и
так далее.
Давайте в качестве примера с помощью
оператора цикла while вычислим вот такую вот сумму:
Расписывать все
это через тысячу слагаемых не очень то удобно. И к тому же число слагаемых
может зависеть от значения переменной и быть неопределенным. В таких задачах
без циклов не обойтись. И программа будет выглядеть так:
S=0; i=1
while i <= 1000:
S += 1/i
i += 1
print(S)
В качестве
выражения в цикле while можно писать все те же самые условия,
что и в условном операторе if. Например, можно вычислять сумму S пока либо i<=1000, либо S < 5. Такое
условие запишется так:
while i <= 1000 and S < 5:
здесь цикл будет
работать пока i<=1000 и S<5 как только
одно из подусловий станет ложным, все составное условие становится ложным и
цикл завершит свою работу.
Вернемся к нашему спортсмену, бегущему
по стадиону. И предположим, что прошел час, но бегун еще не завершил полный
круг. Что произойдет? Цикл сразу завершится? Нет, проверка условия завершения
происходит только на начальной отметке, то есть, спортсмен должен добежать круг
целиком и только потом проверить: прошел час или нет.
Другими словами, пока целиком не
выполнится текущая итерация тела цикла, оператор while продолжает свою
работу. И как только условие цикла становится ложным, то бегун останавливается
и цикл завершает свою работу.
А что будет, если условие в цикле while будет истинным
всегда? В этом случае мы получим «вечный» цикл, программа фактически зависнет и
наш спортсмен будет обречен на бесконечный бег по кругу.
S=0; i=1
while 1 : S += 1
print(S)
Далее, цикл while может иметь
необязательный блок else, который идет после цикла:
Это, вроде как естественный выход из
оператора цикла. В нашей иллюстрации это может быть традиционное посещение
спортсменом душа после пробежки.
И здесь часто возникает вопрос: а чем
блок else отличается от
блока операторов, просто идущих после блока while? Ведь когда
цикл while завершится, мы
так и так перейдем к последующим операторам! Однако, тут есть один нюанс. Любой
оператор цикла в Python может быть досрочно прерван с помощью
оператора
break
Как только он встречается в теле цикла,
цикл (в данном случае while) завершает свою работу. Это как если вдруг возник пожар и
спортсмен не дожидаясь окончания круга спешно бежит со стадиона. В этом случае
спортсмену уже не до душа, он сразу хватает свои вещи и убегает из спортивного
комплекса. То есть, при досрочном прерывании работы цикла while, конструкция else не выполняется
и управление переходит на последующие операторы. Вот в чем отличие блока else от операторов,
стоящих непосредственно после while. Например:
S=0; i=-10
while i < 100:
if i == 0: break
S += 1/i
i=i+1
else:
print("Сумма вычислена корретно")
print(S)
Если здесь при
вычислении суммы ожидается деление на 0, то срабатывает break и цикл досрочно
прерывается. В этом случае блок else не срабатывает и мы не видим сообщения,
что сумма вычислена корректно. Если же все проходит штатно (без вызова break), то в консоли
появляется сообщение
Сумма вычислена корректно
означающее
выполнение блока else.
Раз уж мы начали
говорить об управляющем операторе break, сразу отметим
второй подобный оператор
continue
Этот оператор
позволяет пропускать тело цикла и перейти к следующей итерации, не прерывая
работу самого цикла. Например, мы хотим перебрать все целые значения от -4 до
4, исключая значение 0. Такую программу можно реализовать так:
S=0; i=-5
while i < 4:
i=i+1
if i == 0: continue
print(i)
S += 1/i
print(S)
При выполнении
этой программы увидим, что в консоль выведены все значения кроме нуля. Так как
при i=0 срабатывает
условие и выполняется оператор continue. Все что находится после этого
оператора пропускается и цикл продолжается уже со значением i=1.
Вот так работают
эти два управляющих оператора break и continue, которые можно
использовать во всех операторах циклов.
Оператор цикла for
Следующий и,
наверное, самый часто используемый оператор цикла – это оператор for, который имеет
такой синтаксис:
for <переменная> in <список> :
операторы 1…N
Например,
for x in 1,5,2,4:
print(x**2)
выведет в
консоль квадраты соответствующих чисел. Но что, если мы хотим перебрать
значения по порядку в соответствии с правилом:
начальное
значение, шаг, конечное значение
Для этого
используется генератор последовательностей
range(start, stop, step)
Например, если
мы запишем его вот так:
for x in range(1,5,1):
print(x)
то в консоли
увидим числа от 1 до 4 с шагом 1. То есть, range генерирует
последовательность в интервале
[1;5)
Последнее
значение не входит в интервал. Если в нашем примере поставить шаг отрицательный
-1, то конечное значение 5 не может быть достигнуто и в этом случае Python возвратит пустую
последовательность:
for x in range(1,5,-1):
print(x)
Если нам нужны
числа от 5 до 1, то следует записывать range в таком виде:
for x in range(5,0,-1):
print(x)
Причем, в range можно записывать
только целые числа, с вещественными он не работает.
Давайте
перепишем нашу программу подсчета суммы
с помощью цикла for, получим:
S=0
for i in range(1, 1001, 1):
S += 1/i
print(S)
Здесь весь цикл
записан буквально в одну строчку, а тело цикла состоит из одного оператора –
подсчета суммы ряда.
Вторым примером
рассмотрим задачу вычисления значений линейной функции
Программа будет
выглядеть так:
k = 0.5; b = 2
lst = [0, 0.1, 0.2, 0.3, 0.4, 0.5]
for x in lst:
print(x*k+b)
Этот пример
показывает, что для перебора значений счетчика x можно
использовать списки, сформированные ранее в программе. (О списках мы подробнее
будем говорить на последующих занятиях). Здесь же приведем еще один пример:
msg = "Hello World!"
for x in msg:
print(x)
Он показывает,
что строку можно воспринимать как список и перебирать с помощью цикла for.
Также в цикле for можно
использовать блок else, о котором мы говорили ранее:
for <переменная> in <список> :
операторы 1…N
else:
операторы 1…N
Вложенные циклы
Итак, мы с вами
рассмотрели два оператора циклов: while и for. Все эти циклы
можно комбинировать друг с другом. То есть, создавать вложенные циклы (цикл
внутри цикла).
Как это работает?
Представьте, что бегун начинает бежать по большому кругу, но затем, для
продолжения бега, ему необходимо сделать еще несколько вложенных кругов, после
чего он возвращается на большой круг и продолжает свой бег.
В частности, такие вложенные циклы очень
полезны для перебора элементов матрицы
Тогда мы делаем первый цикл от 1 до N и вложенный от
1 до M
A = [ [1,2,3], [4,5,6] ]
N=2; M=3
for i in range(N):
for j in range(M):
print(A[i][j])
print()
Или для подсчета
вот такой двойной суммы ряда
Программа будет выглядеть так:
S=0; M=10; N=5
for i in range(1,N+1):
for j in range(1,M+1):
S += i*j
print(S)
Мы здесь сначала
пробегаем все значения j от 1 до M при
фиксированном i=1, затем,
значение i увеличивается
на 1, становится 2 и при этом i снова пробегаются значения j от 1 до M. И так пока i не превысит
значение N. То есть,
второй цикл вложен вот в этот первый. И таких вложений можно делать сколько
угодно.
Вот так работают
операторы циклов в Python и теперь вы знаете как их можно
применять на практике.