Перейти к содержанию

412 уроков, 25 библиотек и челлендж «Что выведет код?» — бесплатно, код прямо в браузере

Начать обучение
Урок 7 из 20 Начальный 15 мин 100 XP

Оператор continue в Python: пропуск итерации

continue пропускает остаток тела для текущего элемента и переходит к следующему: не выход из цикла, а фильтр в потоке. Сравниваем с break на одних данных.

Редакция Питоники

break из прошлого урока обрывает перебор целиком. Но чаще задача мягче: не «остановить цикл», а «этот элемент не трогать, остальные — обработать». Температуры ниже нуля в отчёт не идут, пустые строки в логе пропускаются, слишком дорогие товары не берём — а цикл должен продолжаться. Для такого пропуска в Python есть оператор continue: он завершает текущую итерацию досрочно и отправляет цикл к следующему элементу.

continue: пропустить шаг

Печатаем температуры, но отрицательные пропускаем — в отчёте им не место:

пропуск отрицательных
temps = [21, -5, 19, -2, 24]
for t in temps:
    if t < 0:
        continue
    print(f'{t} градусов')
Вывод
21 градусов
19 градусов
24 градусов

Ход программы: 21 печатается. -5 не проходит проверку на положительность? Наоборот: -5 < 0 верно, ветка if срабатывает, и continue прыгает к следующей итерации — строка печати для -5 не выполняется. Затем печатаются 19 и 24, а -2 пропускается тем же способом. Цикл сделал все пять шагов — но печать из тела сработала трижды. continue пропускает остаток тела для текущего элемента, а цикл переходит к следующему.

Фильтрация: оставляем нужное

Пропуск — это фильтр в потоке данных: условие в начале тела работает привратником, внутрь проходит только подходящее. Отбираем товары по карману:

только доступные цены
prices = [89, 240, 42, 590, 130]
for price in prices:
    if price > 150:
        continue
    print(f'по карману: {price}')
Вывод
по карману: 89
по карману: 42
по карману: 130

Проверка стоит в самом начале тела — это общая схема фильтра: сначала отбраковка неподходящих, затем полезная работа. Слишком дорогие цены continue выводит из рассмотрения, не затрачивая на них ни одной строки работы. Тот же приём чистит списки от мусора — пустых значений:

пропуск пустых строк
queue = ['Анна', '', 'Борис', '']
for name in queue:
    if name == '':
        continue
    print(f'Приглашение для {name}')
    print('письмо отправлено')
Вывод
Приглашение для Анна
письмо отправлено
Приглашение для Борис
письмо отправлено

Пустая строка в списке — пропущенное приглашение: письма для неё не отправились, потому что continue прыгнул до обеих строк тела. Обратите внимание: пропускается весь остаток тела, сколько бы строк там ни было. Всё, что написано ниже continue, для отбракованного элемента не выполнится — располагайте продолжение осмысленно: сначала фильтр, потом работа.

Три способа отфильтровать одно и то же

Один и тот же отбор можно записать тремя способами, и разница между ними — не в результате, а в том, где живёт решение. Continue выносит отказ в начало тела, обычный if оставляет отсев в середине, генератор списка вообще убирает цикл в одну строку. На маленьких данных все три дают одинаковый ответ, и выбирать приходится по читаемости.

отбор через continue
temps = [18, 25, 30, 11, 27]

skipped = []
for t in temps:
    if t < 25:
        skipped.append(t)
        continue
    print('жарко:', t)
print('пропущено:', skipped)
Вывод
жарко: 25
жарко: 30
жарко: 27
пропущено: [18, 11]

Тут continue делает две работы: отбрасывает холодные и заодно складывает их в отдельный список skipped. Такая схема — «собери мусор в сторону, работай с остальным» — встречается в чистке данных и в разборе логов. Заметьте, что код для отсева стоит первым: всё, что ниже, работает только с нужными элементами.

Тот же отбор обычным if выглядит иначе — без continue, но с веткой else:

тот же результат через if
temps = [18, 25, 30, 11, 27]
for t in temps:
    if t >= 25:
        print('жарко:', t)
    else:
        print('холодно:', t)
Вывод
холодно: 18
жарко: 25
жарко: 30
холодно: 11
жарко: 27

Вывод другой только потому, что в этой версии мы печатаем и отброшенные элементы. Фильтр как таковой никуда не делся — просто решение «что делать с неподходящим» теперь выражено веткой else, а не оператором continue.

continueif с elseГенератор списка
Где живёт отборв начале телав середине телав одной строке
Что делать с плохиминичегосвоя ветка кодатолько отбор
Результатпечать или накоплениепечать или накоплениеготовый новый список
Когда читается лучшеплохих элементов многоу плохих тоже есть работанужен сам список

continue против break

Оба оператора обрывают текущую итерацию, но урезают разное. Одинаковая проверка и одинаковый список — два варианта поведения:

continue: цикл жив
for n in [1, 2, 3, 4, 5]:
    if n == 3:
        continue
    print(n)
Вывод
1
2
4
5
break: цикл кончен
for n in [1, 2, 3, 4, 5]:
    if n == 3:
        break
    print(n)
Вывод
1
2

Тройка не напечатана в обоих случаях — но дальше пути расходятся. continue после тройки продолжил перебор: в выводе есть 4 и 5. break покинул цикл на тройке: четвёрка и пятёрка вообще не перебирались. Правило для выбора: элемент плохой, а данные в целом нужные — continue; дальнейший перебор бессмыслен — break.

continuebreak
Пропускает остаток тела текущего шагаВыходит из цикла целиком
Цикл продолжается со следующим элементомПеребор прекращён немедленно
Срабатывает многократно: на каждом плохом элементеСрабатывает один раз — и цикл кончен
Оставшиеся элементы обрабатываютсяОставшиеся элементы не смотрятся

continue и накопление

С continue аккумулятор работает предсказуемо: пропущенный элемент просто не попадает в сумму, а сам цикл продолжает с следующего. Это ровно то поведение, которое нужно при чистке данных — нули в оценках, пустые чеки, битые записи.

сумма без нулей
scores = [82, 0, 91, 0, 75]
total = 0
for s in scores:
    if s == 0:
        continue
    total = total + s
print(total)
Вывод
248

82 + 91 + 75 = 248. Нули пропущены, но цикл не прервался — в отличие от break, который остановил бы перебор на первом же нуле и потерял всё, что дальше. Сумма получилась полной, а нули не испортили результат.

У continue есть и вторая роль — собрать результат в отдельный список:

только те, кому пишем
names = ['Анна', '', 'Борис']
sent = []
for name in names:
    if name == '':
        continue
    sent.append(name)
print('отправлено:', sent)
print('всего в списке:', len(names))
Вывод
отправлено: ['Анна', 'Борис']
всего в списке: 3

В исходном списке было три записи, а отправлено две — пустая строка отсеялась на continue. Это готовый приём для данных с пропусками: сначала чистим, потом работаем. Кстати, встроенная функция filter делает ровно то же, но в одну строку: filter(lambda s: s != 0, scores).

continue по словарю

Словарь перебирается так же, как список, и continue в нём работает так же: пары, которые не проходят проверку, просто пропускаются.

только дешёвые товары
prices = {'молоко': 89, 'хлеб': 42, 'сыр': 590}
for name, price in prices.items():
    if price > 200:
        continue
    print(name, price)
Вывод
молоко 89
хлеб 42

Сыр дороже двухсот, поэтому пара пропущена целиком — и печать, и всё, что стояло бы ниже по телу, для него не выполняются. Молоко и хлеб напечатаны. Если бы мы вместо continue написали break, цикл закончился бы на сыре и хлеб мы бы уже не увидели — но перебор шёл бы в порядке вставки, где сыр последний, так что на этом примере разница не проявляется. Поменяйте порядок — и проявится.

continue в while: порядок строк решает

В цикле while у continue есть собственная ловушка. Пропуск тела — это и пропуск изменения переменной условия, если та меняется ниже. Цикл застревает:

continue выше изменения счётчика
# Опасно: continue прыгнет к проверке, так и не уменьшив n
n = 5
while n > 0:
    if n == 3:
        continue
    print(n)
    n = n - 1
Не запускаем: при n = 3 continue прыгает к проверке, строка n = n - 1 не выполняется, и тройка повторяется бесконечно. В песочнице такой цикл зависнет.

Безопасный порядок выглядит так — счётчик двигается первым, проверка идёт следом:

правильный порядок в while
n = 5
while n > 0:
    n = n - 1
    if n % 2 == 0:
        continue
    print('осталось', n)
Вывод
осталось 3
осталось 1

Чётные значения 4 и 2 отброшены, а 3 и 1 напечатаны. Счётчик при этом уменьшился на каждом шаге, поэтому цикл спокойно дошёл до конца. Поменяйте две строки местами — и тот же код зациклится на значении 4.

Фильтр чаще всего нужен при переборе строк текста — пустые строки, служебные записи, шум. Разберём лог, где между записями затесались пустые строки; режем текст на строки методом split, знакомым по уроку про split:

лог без пустых строк
log = 'вход\n\nошибка\n\nвыход'
for line in log.split('\n'):
    if line == '':
        continue
    print(f'запись: {line}')
Вывод
запись: вход
запись: ошибка
запись: выход
фильтр коротких слов
words = ['кот', 'пароход', 'ёж', 'пустыня']
for w in words:
    if len(w) > 4:
        continue
    print(f'короткое: {w}')
Вывод
короткое: кот
короткое: ёж
  • чистка данных: пустые строки, нули, отрицательные температуры, мусорные записи;
  • фильтр по порогу: цены по карману, короткие слова, лёгкие файлы;
  • guard-проверка в начале тела: отбраковать неподходящее до дорогой работы;
  • полная противоположность по эффекту — break из предыдущего урока: он не пропускает шаг, а кончает цикл.

continue и break вместе закрывают управление ходом цикла: плохое — пропустить, цель достигнута — выйти. Дальше в разделе — вложенные циклы, где оба оператора работают на своём уровне.

Что выведет код?

Сначала предскажи ответ в голове — это главный навык программиста.

for n in [1, 2, 3, 4, 5]:
    if n == 3:
        continue
    print(n)
for ch in 'фокус':
    if ch == 'у':
        continue
    print(ch)
n = 4
while n > 0:
    n = n - 1
    if n == 2:
        continue
    print(n)
Проверь себя
0 / 9

1. Что делает continue?

2. Список [1, 2, 3, 4, 5], continue при n == 3. Сколько строк напечатает цикл?

3. Выполнятся ли строки тела, написанные после continue, для отбракованного элемента?

4. Чем опасен continue, поставленный выше строки n = n - 1 в while?

5. Для какой задачи continue подходит лучше, чем break?

6. Что напечатает цикл по строке 'фокус' с continue при ch == 'у'?

7. Как посчитать сумму списка, не учитывая нули?

8. Что произойдёт, если continue стоит в теле цикла по словарю?

9. Чем continue отличается от обычного if с веткой else?

Карточки терминов
Запомнено: 0 / 8
Практика

В логе log = 'утро вечер' между записями затесались пустые строки. Разбери лог на строки через split('\n') и напечатай только непустые в формате «запись: {строка}».

practice.py
Вопросы и ответы по уроку

Что делает continue в Python?

Пропускает остаток тела цикла и переходит к следующей итерации: строки после continue для текущего элемента не выполняются, но сам цикл продолжается. Это фильтр: плохие элементы отбраковываются, поток данных идёт дальше.

Чем continue отличается от break?

continue пропускает только текущий шаг: цикл продолжается со следующим элементом. break завершает весь цикл немедленно. На списке [1, 2, 3, 4, 5] с continue при n == 3 напечатается 1, 2, 4, 5; с break — только 1, 2.

Урок 6: break — выход из цикла

Почему с continue цикл while зависает?

Если continue стоит выше строки, меняющей переменную условия (например, n = n - 1), то при срабатывании уменьшение пропускается, условие остаётся истинным — цикл повторяется вечно. Правило: в while двигайте счётчик до continue.

Как пропустить пустые строки при переборе текста?

Разобрать текст на строки split('\n') и отбраковывать пустые: for line in lines: if line == '': continue. Печать или обработка после continue коснутся только содержательных строк.

Урок 3: for по строке и строкам файла

Как отфильтровать список, не печатая отброшенные элементы?

Поставьте проверку в начало тела: if условие: continue. Всё, что ниже, будет работать только с подходящими элементами, а отсеянные пройдут мимо. Если отброшенные тоже нужно показать — заведите для них отдельный список и складывайте туда до continue.

Почему continue опасен именно в цикле while?

В for следующий элемент берётся у списка, а в while переменную условия двигаете вы сами. Если continue стоит выше строки с шагом, счётчик не уменьшится, условие останется истинным и цикл зависнет. В while всегда двигайте счётчик до continue.

Понравился урок? Сошлитесь на него

«continue пропускает остаток тела для текущего элемента, а цикл переходит к следующему.»

Скопируйте готовую ссылку в формате HTML, Markdown или чистый адрес и вставьте в статью на Habr, VC, Telegram-канал или свой блог — так о проекте узнают новые читатели.

TelegramVK

Что дальше

Осталось в разделе: 20 из 20. Прогресс хранится в вашем браузере.

Похожие уроки по темам

Подобраны автоматически по пересечению тем и ключевых слов.