Как работает continue в Python: пропуск итерации с примерами


Когда я начинал писать парсеры логов на Python, код быстро превращался в лесенку из вложенных if/else. Потом я открыл для себя continue и вместо пяти уровней вложенности получил плоский читаемый цикл. Инструкция continue прерывает текущую итерацию цикла и передаёт управление обратно к проверке условия (в while) или к следующему элементу (в for). Строки, расположенные после continue внутри тела цикла, при этом не выполняются.
Эта статья объясняет, как continue работает в for и while, чем отличается от break и pass, и когда замена continue на if/else делает код лучше.
Что делает continue и как работает
Оператор continue возвращает управление в начало цикла. Все инструкции, расположенные ниже continue в теле текущей итерации, Python пропускает. В цикле for управление переходит к следующему элементу последовательности. В цикле while Python возвращается к проверке условия.
Синтаксис
continue это ключевое слово без аргументов. Его записывают на отдельной строке, обычно внутри условной конструкции if:
for элемент in последовательность:
if условие:
continue
# этот код выполнится, только если условие ложно
Без if перед continue все строки ниже него станут недостижимым кодом, и Python выдаст предупреждение.
Пошаговое выполнение
Рассмотрим, что происходит при вызове continue в for:
- Python берёт очередной элемент из итерируемого объекта.
- Выполняет тело цикла сверху вниз.
- Если встречает continue, прекращает выполнение текущей итерации.
- Переходит к шагу 1, берёт следующий элемент.
- Если элементов больше нет, цикл завершается.
Для while алгоритм отличается в шаге 4: вместо взятия следующего элемента Python проверяет условие цикла.
Примеры continue в цикле for
Пропуск определённого значения
Задача: напечатать числа от 0 до 9, пропустив 5.
for i in range(10):
if i == 5:
continue
print(i)
# Вывод: 0 1 2 3 4 6 7 8 9
Когда i равно 5, Python выполняет continue, пропускает print(i) и переходит к i = 6.
Фильтрация строк файла
Типичная задача при обработке текстовых файлов: пропустить пустые строки и комментарии.
fhand = open('config.txt')
for line in fhand:
line = line.rstrip()
if len(line) == 0:
continue
if line[0] == '#':
continue
print(line)
Первый continue пропускает пустые строки. Второй пропускает строки, начинающиеся с #. Остальные строки попадают в print. Такой подход избавляет от вложенных if/else.
Обработка данных с пропуском некорректных записей
raw_data = ['42', 'hello', '17', '', '99', 'N/A', '0']
numbers = []
for item in raw_data:
item = item.strip()
if not item:
continue
try:
numbers.append(int(item))
except ValueError:
continue
print(numbers) # [42, 17, 99, 0]
Пустые строки пропускаются первым continue. Строки, которые не удаётся преобразовать в int, пропускаются вторым continue в блоке except.
Примеры continue в цикле while
Пропуск строк, начинающихся с решётки
Пример из обучения Python: программа читает ввод пользователя, печатает строки, но пропускает те, что начинаются с #.
while True:
line = input('> ')
if line == 'done':
break
if line[0] == '#':
continue
print(line)
print('Завершено!')
Вывод:
> hello there
hello there
> # не печатай это
> print this!
print this!
> done
Завершено!
Когда пользователь вводит строку с # в начале, continue отправляет управление обратно к while True, и print не выполняется.
Валидация ввода
results = []
while len(results) < 5:
value = input('Число (1-100): ')
if not value.isdigit():
print('Введите целое число')
continue
num = int(value)
if num < 1 or num > 100:
print('Число вне диапазона')
continue
results.append(num)
print('Собрано:', results)
Каждый continue возвращает к проверке len(results) < 5. Некорректный ввод не попадает в список, и цикл продолжает запрашивать данные.
Важно: обновляйте счётчик до continue
Распространённая ловушка: если continue стоит до строки с обновлением переменной-счётчика, цикл зависнет.
# ОШИБКА: бесконечный цикл
i = 0
while i < 10:
if i == 5:
continue # i не увеличивается, вечно проверяет i == 5
print(i)
i += 1Исправление: обновлять счётчик до проверки с continue.
# ПРАВИЛЬНО
i = 0
while i < 10:
i += 1
if i == 5:
continue
print(i)
# Вывод: 1 2 3 4 6 7 8 9 10Эта ошибка не возникает в for, потому что итерационная переменная обновляется автоматически.
Чем continue отличается от break и pass
Три инструкции управления циклом решают разные задачи.
Пример, где все три работают в одном цикле:
for line in open('data.txt'):
line = line.strip()
# pass: заглушка для будущей логики
if line.startswith('TODO'):
pass # обработать позже
# continue: пропустить пустые строки
if not line:
continue
# break: остановиться на маркере конца
if line == 'END':
break
print(line)
continue и вложенные циклы
Инструкция continue влияет только на ближайший цикл, в котором она находится. Во вложенных конструкциях это создаёт путаницу.
for i in range(3):
for j in range(3):
if j == 1:
continue # пропускает j == 1, НЕ i
print(f'i={i}, j={j}')
Вывод:
i=0, j=0
i=0, j=2
i=1, j=0
i=1, j=2
i=2, j=0
i=2, j=2
continue пропускает итерацию внутреннего цикла (j == 1), но внешний цикл по i выполняется полностью.
Как пропустить итерацию внешнего цикла
Python не поддерживает синтаксис вроде continue 2 (как PHP). Есть три обходных пути.
Способ 1: флаговая переменная.
for i in range(5):
skip = False
for j in range(5):
if i + j == 6:
skip = True
break
if skip:
continue
print(f'i={i}')
Способ 2: вынести внутренний цикл в функцию.
def check_row(i):
for j in range(5):
if i + j == 6:
return False
return True
for i in range(5):
if not check_row(i):
continue
print(f'i={i}')
Второй способ считается самым читаемым.
continue vs if/else: что выбрать
Оператор continue можно заменить конструкцией if/else. Разница в читаемости и уровне вложенности.
Вариант с continue (плоская структура)
for item in data:
if not validate(item):
continue
if not transform(item):
continue
save(item)
Вариант с if/else (вложенная структура)
for item in data:
if validate(item):
if transform(item):
save(item)
При двух проверках разница небольшая. При пяти-шести проверках вариант с continue спасает от пирамиды вложенности. Этот приём называют ранним выходом (early return) по аналогии с ранним return в функциях.
Когда if/else лучше
Если после проверки нужно выполнить альтернативное действие, if/else нагляднее:
for num in numbers:
if num % 2 == 0:
even_count += 1
else:
odd_count += 1
Использование continue здесь не даёт выигрыша и запутает читателя.
Практический пример: парсинг лог-файла
Задача: извлечь email-адреса из строк лог-файла, которые начинаются с "From ".
emails = []
fhand = open('mbox-short.txt')
for line in fhand:
line = line.rstrip()
words = line.split()
# Пропускаем пустые строки
if len(words) == 0:
continue
# Пропускаем строки, не начинающиеся с 'From'
if words[0] != 'From':
continue
# Пропускаем строки с недостаточным числом полей
if len(words) < 3:
continue
emails.append(words[1])
print(emails)
Без continue этот код выглядел бы так:
for line in fhand:
line = line.rstrip()
words = line.split()
if len(words) > 0:
if words[0] == 'From':
if len(words) >= 3:
emails.append(words[1])
Три уровня вложенности вместо нуля. С continue каждая проверка отсеивает негодные строки, и основная логика остаётся на первом уровне отступа.
Работает ли continue с генераторами и comprehension
В генераторных выражениях и list comprehension нельзя использовать continue, потому что эти конструкции не являются циклами в привычном смысле. Фильтрацию делают через if:
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
odd = [n for n in numbers if n % 2 != 0]
print(odd) # [1, 3, 5, 7, 9]Условие if n % 2 != 0 работает как continue: элементы, не прошедшие проверку, не попадают в результат.
В генераторной функции с yield инструкция continue работает как обычно:
def odd_numbers(limit):
for n in range(limit):
if n % 2 == 0:
continue
yield n
print(list(odd_numbers(10))) # [1, 3, 5, 7, 9]
Неочевидные детали
Первый факт: continue внутри блока try срабатывает до выполнения except. Но блок finally выполнится в любом случае.
for i in range(3):
try:
if i == 1:
continue
finally:
print(f'finally: {i}')
print(f'после try: {i}')
# Вывод:
# finally: 0
# после try: 0
# finally: 1 (continue сработал, но finally выполнился)
# finally: 2
# после try: 2
Второй факт: continue и else-блок цикла. Оператор continue не влияет на выполнение блока else. Блок else выполнится, если цикл завершился без break. continue не считается прерыванием цикла.
Третий факт: в байт-коде CPython continue компилируется в инструкцию JUMP_ABSOLUTE (или JUMP_BACKWARD в Python 3.12+), которая просто перемещает указатель исполнения к началу цикла. Никаких дополнительных затрат по сравнению с if/else нет.
Четвёртый факт: до Python 3.8 использование continue внутри блока finally вызывало SyntaxError. Начиная с Python 3.8 это ограничение снято.
FAQ
Можно ли использовать continue вне цикла?
Нет. Python выбросит SyntaxError: 'continue' not properly in loop. Инструкция continue допустима только внутри for или while.
Влияет ли continue на производительность?
Нет. На уровне байт-кода continue выполняет один безусловный переход. Это та же операция, что и переход в конец блока if. Разница в производительности с if/else отсутствует.
Как пропустить несколько итераций за раз?
continue пропускает только текущую итерацию. Пропуск нескольких элементов подряд реализуется через итератор:
it = iter(range(10))
for i in it:
if i == 3:
next(it, None) # пропустить 4
next(it, None) # пропустить 5
continue
print(i)
# Вывод: 0 1 2 6 7 8 9
Работает ли continue с циклом do-while?
В Python нет конструкции do-while. Её имитируют через while True с break, и continue в таком цикле работает стандартно.
Что произойдёт, если continue стоит последней строкой в теле цикла?
Ничего полезного. Цикл и так перешёл бы к следующей итерации. Такой continue избыточен, и линтеры (pylint, flake8) могут выдать предупреждение.
Мой совет: используйте continue как фильтр в начале тела цикла. Каждый continue отсекает один класс нежелательных данных, и основная логика остаётся на минимальном отступе. Если continue оказался в середине или конце тела цикла, скорее всего, if/else справится лучше.

.svg.webp)





