Ключевое слово break
, как и в C, прерывает выполнение ОДНОГО блока for
или while
и выходит из него. Другими словами, break
используется для выхода из охватывающего цикла. Итак, есть вложенный цикл, так как-же можно выйти из двух циклов, как только, например, найдем число 3?
my_list = [[1, 2], [3, 4], [5, 6]] for sublist in my_list: for element in sublist: print(f"Проверка {element}") if element == 3: # ...?
Использование break
не поможет, т.к. он остановит внутренний цикл for
, при этом внешний цикл продолжит работать. То есть, если поместить туда break
и запустить код, то можно увидеть как обрабатывается sublist = [5, 6]
:
my_list = [[1, 2], [3, 4], [5, 6]] for sublist in my_list: for element in sublist: print(f"Проверка {element}") if element == 3: break # Проверка 1 # Проверка 2 # Проверка 3 # Проверка 5 # Проверка 6
Есть несколько способов обойти эту трудность, например, использовать какой нибудь флаг:
my_list = [[1, 2], [3, 4], [5, 6]] # определим флаг для выхода из циклов flag = False for sublist in my_list: for element in sublist: print(f"Проверка {element}") if element == 3: # выходим из внутреннего цикла flag = True break if flag: # выходим из внешнего цикла break # Проверка 1 # Проверка 2 # Проверка 3
А можно использовать генераторы. Идея заключается в том, что бы вынести циклы в отдельный генератор, а затем использовать этот генератор вместо исходных циклов.
# определим генератор с циклами # внутри из предыдущего примера def elements_from_sublists(my_list): for sublist in my_list: for element in sublist: yield element
Затем используем этот генератор в исходном фрагменте кода:
my_list = [[1, 2], [3, 4], [5, 6]] for element in elements_from_sublists(my_list): print(f"Проверка {element}") if element == 3: break # Проверка 1 # Проверка 2 # Проверка 3
Теперь есть только один цикл, поэтому ключевое слово break
работает идеально. Стратегия выделения логики цикла в генератор может быть весьма полезной. Для данного конкретного случая в стандартной библиотеке уже есть лучшая альтернатива itertools.chain()
:
from itertools import chain my_list = [[1, 2], [3, 4], [5, 6]] for element in chain.from_iterable(my_list): print(f"Проверка {element}") if element == 3: break
else
в циклахОператоры цикла могут иметь блок else
, который выполняется, когда цикл заканчивается исчерпанием итерируемого объекта для for
или когда условие становится ложным для while
, но не тогда, когда цикл завершается оператором break
. Это иллюстрируется следующим циклом, который ищет простые числа:
>>> for n in range(2, 10): ... for x in range(2, n): ... if n % x == 0: ... print(n, 'equals', x, '*', n//x) ... break ... else: ... # loop fell through without finding a factor ... print(n, 'is a prime number') ... # 2 is a prime number # 3 is a prime number # 4 equals 2 * 2 # 5 is a prime number # 6 equals 2 * 3 # 7 is a prime number # 8 equals 2 * 4 # 9 equals 3 * 3
Это правильный код. Посмотрите внимательно, инструкция else
относится к блоку цикла for/in
, а не к оператору if
.
Оператор else
в циклах, имеет больше общего с else
в конструкциях с try
, чем в конструкциях с if
. В конструкциях с оператором try
, else
выполняется тогда, когда не поднимается исключение, и оператор цикла else
выполняется тогда, когда не срабатывает break. Подробнее о конструкциях try/except/else/finally
и исключениях смотри в разделе Обработка исключений.
continue
в циклахКлючевое слово continue
, заимствован из языка C. Если ход цикла встречает это ключевое слово, то будет пропущен один шаг. Другими словами, цикл продолжится со следующей итерации:
>>> for num in range(2, 10): ... if num % 2 == 0: ... print("Found an even number", num) ... continue ... print("Found a number", num) ... # Found an even number 2 # Found a number 3 # Found an even number 4 # Found a number 5 # Found an even number 6 # Found a number 7 # Found an even number 8 # Found a number 9