В Python можно писать else не только после if, но и после циклов for и while. Тело else выполняется только тогда, когда цикл завершился "штатным" образом — не по break. Это позволяет элегантно реализовать, например, поиск элемента.
Пример:
for x in range(5): if x == 3: print('break!') break else: print('Цикл завершён без break') # не выполнится
for x in range(5): if x == 10: break else: print('Цикл завершён без break') # выполнится
Эта фича часто используется для "поиска без успеха": если break не случился, значит элемент не найден.
Всегда ли блок else цикла выполняется, если цикл завершился? Что если цикл был пустой?
Ответ: Да, если не было break, else всегда выполнится, даже если цикл ни разу не вошёл в тело:
for x in []: print('ничего') else: print('else!') # это будет выведено
История
Проект: Парсер документов.
Проблема: Искали ключ в списке, и после цикла ставили флаг "not found" вне else. В результате обнаружение элемента работало некорректно, если break не срабатывал.
История
Проект: Генерация уникальных токенов.
Проблема: Логика генерации токена зависела от корректного выхода по break, и else ошибочно считался "исключительным случаем", хотя по факту срабатывал в 99 % запусков, что ломало логику авторизации пользователей.
История
Проект: Тестирующий скрипт для сетевого API.
Проблема: Из-за неверного понимания else после while использовали его для обработки таймаута, хотя цикл завершался не по break, и таймауты не ловились, что приводило к "тихим" ошибкам в тестах.