Сообщить об ошибке.

Поведение цикла, при использовании инструкций break, continue и else

Ключевое слово 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