Цикл for
Цикл for
, также называемый циклом с параметром, в языке Питон богат возможностями. В цикле
for
указывается переменная и множество значений, по которому будет пробегать переменная.
Множество значений может быть задано списком, кортежем, строкой или диапазоном.
Вот пример использования цикла, где в качестве множества значений используется кортеж (набор констант):
for prime_number in 2, 3, 5, 7, 11, 13, 17, 19:
print(prime_number)
В этом примере переменная prime_number последовательно принимает значения 2
, 3
, 5
, 7
, 11
,
13
, 17
, 19
. На каждом шаге цикла выводится очередное простое число. Как и в условном
операторе, для того чтобы указать операторы, которые должны выполняться на каждом шаге
цикла, используется отступ относительно строки, начинающейся словом for
. Рекомендуем в
качестве отступа использовать 4
пробела, а не, например, табуляцию (она может по-разному
выглядеть в различных текстовых редакторах).
В списке значений могут быть выражения различных типов, например:
for i in 1, 2, 3, 'one', 'two', 'three':
print(i)
При первых трех итерациях цикла переменная i будет принимать значение типа int, при последующих трех — типа str. Но это скорее нетипичное использование цикла for.
Функция range
Как правило, циклы for
используются либо для повторения каких-либо действий заданное число
раз, либо для изменения значения переменной в цикле от некоторого начального значения до
некоторого конечного.
Для повторения цикла некоторое заданное число раз n
можно использовать цикл for
вместе с
функцией range
:
for i in range(n):
Тело цикла
В качестве n
может использоваться числовая константа, переменная или произвольное
арифметическое выражение (например, 2 ** 10
). Если значение n
равно нулю или отрицательное,
то тело цикла не выполнится ни разу. Под телом цикла понимается любой набор операторов
(присваивания, печати, условных, цикла и др.) языка Python.
Например,
for i in range(10):
print('Hello!')
Здесь слово Hello!
будет напечатано 10
раз (скопируйте данную программу и проверьте, как это
будет выглядеть).
Немного изменим нашу программу:
for i in range(10):
print('Hello', i)
Теперь наши слова пронумерованы индексной переменной i
, которая последовательно принимает
значения 0
, 1
, …, 9
. То есть в общем случае n
означает количество повторений, а сами значения
индексной переменной меняются от 0
до n-1
включительно.
Если задать цикл таким образом:
for i in range(a, b):
Тело цикла
то индексная переменная i
будет принимать значения от a
до b - 1
, то есть первый параметр
функции range
, вызываемой с двумя параметрами, задает начальное значение индексной
переменной, а второй параметр — первое значение, которая индексная переменная принимать не
будет. Если же b
≥ a
, то цикл не будет выполнен ни разу. Например, для того, чтобы
просуммировать значения чисел от 1
до n
можно воспользоваться следующей программой:
sum = 0
for i in range(1, n + 1):
sum += i
В этом примере переменная i
принимает значения 1
, 2
, ..., n
, и к значению переменной sum
последовательно добавляются указанные значения (операция +=
означает увеличение значения
переменной на величину выражения, стоящего в правой части).
Усложним нашу программу. Пусть нам требуется найти минимум среди n введенных чисел
(значение n
вводится в программу ранее). Вспомним, как мы искали минимум среди трех чисел a
,
b
и c
:
min = a
if b < min:
min = b
if c < min:
min = c
Мы не можем считать n
чисел в n
различных переменных, но в нашем алгоритме они, по сути, не
нужны: можно считывать очередное значение в одну и ту же переменную, сравнивать его с
текущим значением минимума и забывать про него. Первое значение можно сразу считать в
переменную min
, тем самым задав ему начальное значение:
min = int(input())
for i in range(1, n):
a = int(input())
if a < min:
min = a
print(min)
Обратите внимание, что в цикле значение переменной a считывается n-1
раз, а не n
.
Наконец, чтобы организовать цикл, в котором индексная переменная будет, например, уменьшаться,
необходимо использовать функцию range с тремя параметрами. Первый параметр задает
начальное значение индексной переменной, второй параметр — значение, до которого будет
изменяться индексная переменная (не включая его!), а третий параметр — величину изменения
индексной переменной. Например, сделать цикл по всем нечетным числам от 1
до 99
можно при
помощи функции range(1, 100, 2)
, а сделать цикл по всем числам от 100
до 1
можно при
помощи range(100, 0, -1)
.
Более формально: цикл
for i in range(a, b, d):
при d > 0
задает значения индексной переменной i = a
, i = a + d
, i = a + 2 * d
и так для всех
значений, для которых i < b
. Если же d < 0
, то переменная цикла принимает все значения i > b
.
В качестве a
, b
или d
можно использовать не только константы и переменные, но и выражения.
Цикл while
Цикл while
(“пока”) позволяет выполнять одну и ту же последовательность действий, пока
проверяемое условие истинно. Условие записывается до тела цикла и проверяется до выполнения
тела цикла. Как правило, цикл while
используется, когда заранее невозможно определить точное
значение количества проходов исполнения цикла.
Синтаксис цикла while
в простейшем случае выглядит так:
while условие:
блок инструкций
При выполнении цикла while
сначала проверяется условие. Если оно ложно, то выполнение
цикла прекращается и управление передается на следующую инструкцию после тела цикла while
(после блока инструкций). Если условие истинно, то последовательной выполняется блок
инструкций данного цикла (инструкций может быть несколько), после чего условие проверяется
снова и снова выполняется блок инструкций. Так продолжается до тех пор, пока условие будет
истинно. Как только условие станет ложным, работа цикла завершится и управление передастся
следующей инструкции после цикла.
Следующий фрагмент программы напечатает на экран квадраты всех целых чисел от 1
до 10
:
i = 1
while i <= 10:
print(i)
i += 1
В этом примере переменная i
внутри цикла изменяется от 1
до 10
. Такая переменная, значение
которой меняется с каждым новым проходом цикла, называется счетчиком. Заметим, что после
выполнения этого фрагмента значение переменной i
будет равно 11
, поскольку именно
при i=11
условие i<=10
впервые перестанет выполняться. Видно, что цикл while
может
заменять уже известный вам цикл for ... in range(...)
.
Но если условие оказывается истинным всегда (например, когда соответствующие переменные никак не изменяются внутри тела цикла), то цикл штатным образом закончиться не может, при этом говорят, что программа “зацикливается”.
Вот еще один пример уже типичного использования цикла while
для определения количества
цифр натурального числа n
:
n = int(input())
length = 0
while n > 0:
n //= 10
length += 1
print(length)
В этом цикле с помощью целочисленного деления на 10
мы отбрасываем по одной цифре числа,
начиная с конца (n //= 10
, что эквивалентно инструкции n = n // 10
), при этом считаем в
переменной length
, сколько раз это было сделано.
В языке Python есть и другой способ решения конкретно этой задачи:
length = len(str(i))
Обработка последовательностей неизвестной длины
В материалах по циклам for
мы уже рассматривали задачи на обработку числовых последовательностей. С использованием цикла while
подобные задачи можно решать и для
случая, когда заранее не известно число элементов последовательности, а ввод ограничен тем или
иным образом. Рассмотрим пример такой задачи.
В программу вводится последовательность натуральных чисел, заканчивающаяся нулем. Требуется найти произведение этих чисел (очевидно, что ноль не должен участвовать в нахождении произведения). Решение может выглядеть так:
a = int(input())
p = 1
while a != 0:
p *= a
a = int(input())
print(p)
Подумайте, что выдаст эта программа, когда сразу будет введено значение 0
и что скорее всего
логично выдавать в этом случае.
Окончание ввода может быть и более сложным. Например, чтобы 0
сам по себе мог быть членом
последовательности, то окончанием ввода могут служить уже два нуля подряд. Что вынуждает
хранить не только текущее считанное значение, но и предыдущее:
b = int(input())
a = int(input())
…
while a != 0 or b != 0:
# обработка b
b = a
a = int(input())
В этом случае последние два нуля в обработке принимать участия не будут.
Инструкции управления циклом
После тела цикла как и в условном операторе можно написать слово else:
и после него блок
операций, который будет выполнен один раз после окончания цикла, когда проверяемое условие
станет неверно:
i = 1
while i <= 10:
print(i)
i += 1
else:
print('Цикл окончен, i =', i)
Казалось бы, никакого смысла в этом нет, ведь этот же блок инструкций можно просто
написать после окончания цикла. Смысл появляется только вместе с инструкцией break
,
использование которой внутри цикла приводит к немедленному прекращению цикла, при этом не
исполняется и ветка else
. Разумеется, инструкцию break
осмысленно вызывать только из
инструкции if
, то есть она должна выполняться только при выполнении какого-то особенного
условия.
Другая инструкция управления циклом — continue
(продолжение цикла). Если эта инструкция
встречается где-то посередине цикла, то пропускаются все оставшиеся инструкции до конца
цикла, и исполнение цикла продолжается со следующей итерации (в цикле while
— c новой
проверки условия).
Инструкции break
, continue
и ветку else:
можно использовать и внутри цикла for,
причем именно там использование break
часто бывает оправданным. Тем не менее, увлечение
инструкциями break
и continue
не поощряется, если можно обойтись без их использования.
Вот типичный пример плохого использования инструкции break
:
while True:
length += 1
n //= 10
if n == 0:
break
Здесь True
— логическая константа, означающая, что условие всегда истинно, а цикл
закачивается по инструкции break
. Важно также понимать, что в случае вложенных циклов
break завершает выполнение только одного цикла, а не всех сразу. Завершить выполнение, не
только внутреннего, но и внешнего из двух циклов можно, например, с использованием
логической переменной:
f = False
for i in range(N):
for j in range(M):
...
if i*j > K:
f = True
break
# основное тело цикла
if f:
break
Начальное присваивание для переменной f
является обязательным, в противном случае программа
не сможет выполнять строку if f
, так как переменной f
может не существовать (в других языках
программирования при описании f
ей будет присвоено или значение по умолчанию false
или
случайное значение).