2.13. Управление циклом¶
Два ключевых слова меняют то, как выполняется цикл:
break– немедленно выйти из цикла.continue– пропустить остаток текущей итерации и перейти к следующей.
Оба относятся к самому внутреннему циклу, внутри которого они находятся.
2.13.1. break¶
Используйте break, чтобы остановить цикл, как только выполнится условие. Классический шаблон «найти и остановиться»:
found = None
for item in items:
if matches(item):
found = item
break
if found is not None:
print("found:", found)
В цикле while True: именно break завершает цикл:
while True:
line = next_line()
if line == "quit":
break
process(line)
2.13.2. continue¶
Используйте continue, чтобы пропустить остаток тела и перейти к следующей итерации. Удобно для фильтрации элементов внутри цикла:
for n in numbers:
if n < 0:
continue # skip negatives
print(n)
Тот же эффект можно записать как блок if вокруг остальной части тела. Иногда continue понятнее, когда условие пропуска проще сформулировать заранее, чем условие сохранения.
Внутри цикла continue играет ту же роль, что и ранний return в функции: пропустить случаи, которые вы не обрабатываете, и оставить основную работу на внешнем уровне отступа без вложенности. Цикл фильтрации и обработки – это каноническая форма:
for item in items:
if item is None:
continue
if not item.is_valid():
continue
process(item)
Строка с отступом process(item) – это и есть фактическая работа; каждое условие выше точно указывает, какие элементы будут пропущены.
2.13.3. else в цикле¶
И for, и while допускают необязательный блок else. Он выполняется, когда цикл завершается без срабатывания break. Чаще всего это используется в цикле поиска, которому нужен запасной вариант, если ничего не найдено:
for item in items:
if matches(item):
print("found:", item)
break
else:
print("no match")
Если срабатывает break, блок else пропускается. Читайте эту конструкцию как «for X in Y: …; а иначе, если мы ни разу не вышли, выполни Z.»
2.13.4. Распространённые шаблоны циклов¶
Несколько шаблонов часто встречаются в реальных скриптах:
Опрос – ждать, пока некоторое условие не станет истинным, прежде чем продолжить. В теле используется
pass, оператор-заглушка Python; каждый блок с отступом должен содержать хотя бы один оператор, иpass– это способ сказать «здесь ничего не делать»:while not ready(): pass proceed()
Конечный автомат – единственный цикл
while True:, который выбирает, что делать, на основе переменной состояния. Полезно, когда работа чётко разбивается на несколько именованных фаз:state = "header" for line in lines: if state == "header": if line.startswith("---"): state = "body" elif state == "body": print(line)
Накопление – формировать результат при обходе последовательности:
total = 0 for x in samples: total += x mean = total / len(samples)
Многие циклы накопления имеют однострочный эквивалент с использованием встроенной функции. Используйте встроенную функцию, когда она подходит:
sum()– складывает каждый элемент итерируемого объекта.any()–True, если хотя бы один элемент истинный.all()–Trueтолько тогда, когда каждый элемент истинный.sorted()– новый список с элементами по порядку.len()– количество элементов (там, где итерируемый объект знает свою длину).
>>> samples = [3, 1, 4, 1, 5, 9, 2, 6] >>> sum(samples) 31 >>> sum(samples) / len(samples) # mean 3.875 >>> max(samples) 9 >>> min(samples) 1 >>> sorted(samples) [1, 1, 2, 3, 4, 5, 6, 9] >>> any([False, False, True]) True >>> all([True, True, False]) False
Встроенный вариант короче, понятнее и обычно быстрее, чем написанный вручную такой же цикл.