2.4 Счетный цикл#
Синтаксис счётного цикла#
Для задач, которые мы формулируем фразами «Нужно выполнить для каждого элемента из …» и «Нужно выполнить N раз», больше подойдет применение счетного цикла. В нем уже нет условия, на основе которого определяется, надо ли выполнять следующие итерации. Вместо этого циклу указывается некоторый объект - контейнер, составляющие которого будут поочередно перебираться на каждой итерации. Чтобы на начальном этапе глубоко не вдаваться в разнообразие типов данных в Python, скажем, что таким образом в счетных циклах мы будем перебирать некоторые коллекции. Сами коллекции мы поделим на несколько типов данных, более подробное знакомство с которыми произойдет в следующем модуле.
Коллекции - контейнеры, включающие в себя другие объекты
Последовательности - упорядоченные коллекции из любых объектов
Множества - неупорядоченные коллекции из уникальных объектов
Отображения - неупорядоченные коллекции с доступом к объекту по ключу
Чтобы реализовать счетный цикл, перебирающий ту или иную коллекцию, используется следующий синтаксис:
for Объект in Коллекция:
Блок инструкций
На каждой итерации цикла мы будем получать следующий объект из коллекции, пока они не закончатся. Фактически в первой строчке будет производиться операция присваивания, а на месте объекта будет определяться переменная, которая на каждой итерации будет ссылаться на новый объект, полученный из коллекции.
Из различных коллекций нам пока знаком только строковый тип данных, относящийся к последовательностям, поэтому рассмотрим пример работы цикла на нем:
text_sequence = "some text"
# цикл по строке будет перебирать символы внутри строки
for char in text_sequence: # вместо char может быть любое другое имя переменной
print(char) # на каждой итерации в char будет новое значение
s
o
m
e
t
e
x
t
Итерируемые объекты (iterable)
Счетный цикл for работает не только со строками. Его можно использовать с любым итерируемым объектом (iterable).
Итерируемый объект - это любой объект, состоящий из отдельных элементов, по которым можно пройти поочерёдно, получая их один за другим. Например, строка - итерируемый объект, потому что состоит из символов. А число (int) - не итерируемый объект, потому что это единое значение, которое нельзя разбить на отдельные элементы для перебора.
Технически итерируемым считается объект, у которого есть метод __iter__. Именно этот метод позволяет циклу for получать элементы по одному. Если у объекта такого метода нет, то при попытке перебрать его в цикле возникнет ошибка TypeError: '...' object is not iterable.
Далее мы познакомимся с новыми типами данных - списками, кортежами, множествами и словарями - и все они будут итерируемыми объектами, которые можно перебирать в цикле for.
Вложенные циклы#
Циклы можно вкладывать друг в друга - так же, как условия. Внешний цикл выполняет одну итерацию, запуская внутренний цикл, который проходит все свои итерации полностью, после чего внешний цикл переходит к следующей итерации.
На практике вложенные циклы часто используются для обхода двумерных структур - например, матриц или сетки координат:
# Сетка координат: перебор всех пар (x, y)
for x in range(0, 3, 1):
for y in range(0, 2, 1):
print(f"Точка: ({x}, {y})")
Точка: (0, 0)
Точка: (0, 1)
Точка: (1, 0)
Точка: (1, 1)
Точка: (2, 0)
Точка: (2, 1)
Глубина вложенности
Не рекомендуется использовать более 2-3 уровней вложенности - такой код становится трудным для чтения. Если задача требует глубокой вложенности, стоит подумать как организовать код по-другому.
Инструкции управления циклом#
Для счетного цикла доступны все те же необязательные блоки и инструкции, которые встречались в условном цикле. Также можно использовать continue и break для прерываний, else для выполнения инструкций в случае успешного выполнения цикла (когда в нем не произошло прерывания break).
text_sequence = "some text"
for char in text_sequence:
if char == "e":
continue
if char == " ":
break
print(char)
else:
print("Text without spaces")
s
o
m