logo
Ещё

Циклы в Python

В любом языке программирования есть специальные инструменты контроля исполнения – эти инструменты позволяют исполнять программу не последовательно, а в каком-то другом порядке. За ветвление обычно отвечают if-else и switch, а за многократное исполнение – циклы. Python предлагает на выбор 2 вида циклов: while и for, каждый лучше подходит под свой тип задачи. Кроме того, в Python цикл for существенно отличается от реализаций for в других языках программирования – об этом, как и в целом о циклах в Python, рассказываем ниже.

Синтаксис и смысл for и while

Для начала разберемся с циклами как таковыми. Их основная суть – выполнять определенный набор действий, пока истинно некоторое условие. Всего в программировании есть 3 распространенных вида циклов: while, do-while (иногда называют repeat) и for. На блок-схемах они выглядят так:


В чем разница:

  • While. Когда интерпретатор доходит до while – он проверяет условие, если оно возвращает true – интерпретатор исполняет тело цикла. Затем интерпретатор снова проверяет условие, если оно все еще возвращает true – он исполняет тело цикла. Затем интерпретатор снова проверяет условие, если оно все еще возвращает true – …
  • Do-while. То же, что и while, но тело цикла первый раз исполняется до проверки условия – изредка это бывает очень удобно.
  • For. Внутри for существует некий счетчик, который должен досчитать до определенного значения, после которого поток исполнения выйдет из цикла.

Глобальная разница – в том, что while и do-while исполняются неизвестное число раз – «пока не будет выполнено условие». В то же время for используется тогда, когда точно (или достаточно приблизительно) известно, сколько раз нужно отработать циклу – перебор массива, 10 попыток коннекта к удаленному серверу и так далее.

Форма цикла while в Python:

while [условие]:

тело цикла

Для того, чтобы тело цикла исполнялось, условие должно возвращать true. Внутри тела цикла может быть любой код – даже другие циклы. Как это работает на практике:


Цикла do-while в Python нет, поэтому сразу переходим к for. Синтаксис:

for элемент in итерируемый_объект:

тело цикла

For принимает на вход любой итерируемый объект – список, словарь, строку, объект range и так далее. Этот итерируемый объект последовательно перебирается, каждый элемент итерируемого объекта присваивается переменной «элемент», после чего отрабатывает тело цикла:


В других языках программирования циклы for работают по принципу «собери его сам», например – в Golang for будет выглядеть как:

for i := 0; i < 10; i++ {

// тело цикла

}

, то есть мы сами задаем счетчик; в Python «натуральным счетчиком» является количество элементов итерируемого объекта. Это – крайне удобно, когда мы работаем со структурами данных; но что делать, если нам нужен конкретно счетчик – например, мы хотим, чтобы цикл отработал ровно 10 раз?

Для этой задачи в Python есть структура данных range. Она создается через функцию range(), которая принимает 3 параметра:

range([начальное значение,]конечное значение[,шаг])

Параметры в квадратных скобках – опциональные, единственный обязательный параметр – конечное значение. Функция range() возвращает объект-«счетчик», если мы укажем только обязательный параметр – она вернет счетчик, начинающийся с нуля и заканчивающийся числом, на единицу меньшим, чем то, которое мы передали, то есть range(5) вернет счетчик с числами от 0 до 4. [Начальное значение,] позволяет задать, как нетрудно догадаться, начальное значение: range(2,5) вернет счетчик от 2 до 4. Наконец, [,шаг] позволяет вернуть счетчик, в котором числа будут идти с некоторым промежутком – range(3,10,2) вернет счетчик с числами 3, 5, 7 и 9.

Контроль исполнения: break, continue

Иногда бывает удобно досрочно прервать выполнение цикла – либо только текущую итерацию, либо вообще весь цикл. А в случае с бесконечными циклами единственный способ избежать зависания приложения – это прервать цикл. Для того, чтобы пропустить текущую итерацию, есть ключевое слово «continue»; если нужно полностью прервать цикл, используют ключевое слово «break». Пример с continue:

for i in range(1, 10):

if i % 2 == 0:

continue

print(i)

Цикл выводит только нечетные числа, потому что на каждом четном числе срабатывает if, который содержит в себе continue – и цикл досрочно переходит к следующей итерации.

Пример с break:

for i in range(1, 10):

if i == 5:

break

print(i)

Приложение выведет числа от 1 до 4 – на числе 5 сработает if, который содержит в себе break, и весь цикл остановится.

Дополнительные инструменты циклов в Python

Из интересных дополнительных инструментов для циклов можно отметить else, pass и короткую запись цикла.

Циклы for и while в Python позволяют добавить после себя необязательную конструкцию else, инструкции в которой отработают после того, как цикл будет закончен. Пример:

for n in range(2, 10):

for x in range(2, n):

if n % x == 0:

print(f"{n} равно {x} * {n // x}")

break

else:

print(f"{n} является простым числом")

Здесь мы используем вложенный цикл для поиска простых чисел, с помощью else во вложенном цикле мы выводим число, если внутренний цикл не нашел делителей. Что важно: else после цикла сработает только в том случае, если цикл завершился «естественным» образом – условие стало false или for пересчитал все элементы. Если же цикл завершился из-за break, return или генерации исключения, блок else исполняться не будет.

Что касается pass – тут все просто. В языках, в которых блоки кода обозначаются специальными символами (чаще всего – {}), мы можем создать пустой цикл:

for i := 0; i < 10; i++ {

}

В Python так не получится – интерпретатор выдаст ошибку. Чтобы «заткнуть» его, нам нужно использовать операцию-пустышку – pass:

for elem in range(10):

pass

Наконец, Python предоставляет синтаксический сахар для генерации последовательностей – генераторы. Обычно генераторы используются для создания списков и кортежей. Генератор представляет собой однострочный цикл, который вмещает действие, перечисление и условие, синтаксис:

[действие] for [переменная] in [итерируемый_объект] if [условие]

Условие – необязательный элемент. Как пример – генератор, создающий список квадратов четных чисел:

even_squares = [x**2 for x in range(1, 11) if x % 2 == 0]

Здесь мы для всех чисел от 1 до 10 (x in range(1, 11)) помещаем в список (генератор обернут в [] скобки) их квадраты (x**2), но – только в том случае, если число x – четное (if x % 2 == 0).

Варианты использования циклов

С базовыми применениями циклов (перебор, достижение условия) вы и сами разберетесь, мы же рассмотрим более продвинутые вещи.

Первое, что вам может пригодиться – бесконечный цикл. Они бывают крайне удобны – например, если мы пишем сервер, то мы запускаем внутри него бесконечное ожидание и обработку входящих запросов. С помощью цикла for в Python создать бесконечный цикл нельзя (на самом деле – можно, но не делайте так, такой код будет сложно понять), поэтому остается while:

while True:

#что-то делаем

if [условие]:

break

В бесконечные циклы обязательно нужно добавлять break с условием, при котором цикл будет завершаться – иначе вы потеряете контроль над циклом.

Второй прием – вложенные циклы:

for i in range(10):

# тело внешнего цикла

for j in range(20):

# тело внутреннего цикла

Особенно они полезны, когда вам нужно перебрать матрицу, то есть двухмерный массив. Но помните: каждый новый вложенный цикл умножает количество операций на число, равное количеству его срабатываний, то есть рано или поздно у вас могут кончиться ресурсы железа.

Еще одна техника – имитация do-while в Python. Выглядит вот так:

x = 0

while True:

x += 1

print(x)

if x >= 5:

break

То есть мы создаем бесконечный цикл, внутри которого сначала помещаем тело цикла, а затем – условие и break, если условие будет False. Не очень красиво, зато – работает.

Наконец – помните, что связка for и in позволяет перебирать любые iterable. Например – вот как выглядит перебор словаря:

student_scores = {

'Alice': 85,

'Bob': 92,

'Charlie': 78,

'Diana': 90

}

for student, score in student_scores.items():

print(f"{student}: {score}")

.items() возвращает нам кортеж (ключ, значение), который мы автоматически распаковываем в переменные – с ними уже можно работать.

Вывод

Тезисно:

  • Цикл – это управляющая конструкция, которая позволяет несколько раз исполнить один и тот же участок кода.
  • В Python есть 2 цикла – for и while.
  • For обычно используется, когда мы знаем (хотя бы примерно), сколько итераций нужно произвести, while используется, когда мы не знаем, сколько итераций нужно.
  • For принимает любой итерируемый объект, если нам нужен конкретно счетчик – его можно сгенерировать функцией range().
  • С помощью break можно полностью выйти из цикла, с помощью continue можно пропустить текущую итерацию.