Как выйти из цикла for (python)
Есть цикл, он перебирает все комбинации чисел из списка ( lst2 ), методом itertools.combinations_with_replacement . Цель получить последовательность чисел с сумой элементов равной «длине» — width (200 в данном случае) и что бы в выдаче был первый из запрошенных форматов (обозначено formats[0] , в данном случае 50). Код выдает:
(50, 150) (50, 50, 100) (50, 55, 95) (50, 60, 90) (50, 65, 85) (50, 70, 80) (50, 75, 75) (50, 50, 50, 50)
Что полностью соответствует задаче. Проблема в том что цикл не останавливается так как не перебрал все возможные комбинации. Подскажите пожалуйста как я могу из него выйти сохранив при этом нужные мне значения. Благодарю, код ниже.
from itertools import * width = 200 # Длинна материала lst2 = [50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180, 185, 190, 195] # Возможные форматы formats = [50, 60] # Форматы которые должны быть в выдаче lst3 = [] #Список в который записываются трушные варианты for i in range(1, len(lst2) + 1): for a in combinations_with_replacement(lst2, i): if formats[0] in a and sum(a) == width: print(a) lst3 = lst3 + [str(a)] else: pass
5 простых способов выйти из вложенных циклов в Python
Python — элегантный язык программирования. Но у него есть слабые стороны. Иногда Python не так элегантен, как должен быть.
Например, когда нам нужно выйти из вложенных циклов:
for a in list_a: for b in list_b: if condition(a,b): break
break может помочь выйти только из внутреннего цикла. Можем ли мы напрямую выйти из двух вложенных циклов одновременно? Есть ли в Python какие-то встроенные ключевые слова или приемы для этого?
К сожалению, встроенная поддержка этой операции отсутствует.
В Python нет такой возможности, но она есть в других языках, например, PHP:
foreach ($a_list as $a) < foreach ($b_list as $b) < if (condition($a, $b)) < break 2; //break out of 2 loops >> >
В PHP ключевое слово break имеет параметр, который определяет, из скольких вложенных циклов нужно выйти. Значение по умолчанию равно 1, что означает выход из самого внутреннего цикла.
Поскольку Python очень гибкий, у нас есть много других способов получить тот же результат без встроенной поддержки.
В этой статье будут представлены 5 способов выхода из вложенных циклов в Python. А в конце будет упомянуто, как избежать проблемы вложенных циклов, если это возможно.
1. Добавьте флаг
Определим переменную и используем ее в качестве флага. Рассмотрим простой пример:
# add a flag variable break_out_flag = False for i in range(5): for j in range(5): if j == 2 and i == 0: break_out_flag = True break if break_out_flag: break
Как показано выше, переменная break_out_flag — это флаг, сообщающий программе, когда ей следует выйти из внешнего цикла.
Это работает, но код загрязняется, поскольку мы добавляем новую переменную для решения простой задачи.
Давайте рассмотрим другие варианты.
2. Бросить исключение
Если мы не можем использовать ключевое слово break, почему бы не реализовать выход из циклов другим способом? С помощью методов обработки исключений в Python мы можем выйти из вложенных циклов следующим образом:
# raise an exception try: for i in range(5): for j in range(5): if j == 2 and i == 0: raise StopIteration except StopIteration: pass
3. Проверьте то же условие еще раз
Поскольку одно условие приводит к выходну из одного цикла, проверка одного и того же условия в каждом цикле также является допустимым решением. Вот пример:
# check the same condition again for i in range(5): for j in range(5): if j == 2 and i == 0: break if j == 2 and i == 0: break
Приведенный выше способ работает, но это не очень хорошая идея. Это не эффективно и вынуждает нас делать много лишних операций.
4. Используйте синтаксис For-Else
В Python есть специальный синтаксис: «for-else». Он не популярен, а кто-то даже никогда его не использовал. Потому что все привыкли использовать «else» после «if».
Однако, когда дело доходит до разрыва вложенных циклов. Этот нетрадиционный синтаксис может помочь.
# use the for-else syntax for i in range(5): for j in range(5): if j == 2 and i == 0: break else: # only execute when it's no break in the inner loop continue break
Приведенный выше код использует преимущества техники «for-else», поскольку код под оператором else будет выполняться только тогда, когда внутренний цикл завершится без break.
5. Поместите циклы в функцию
Если мы поместим вложенные циклы в функцию, проблема break становится простой. Потому что мы можем использовать ключевое слово return вместо break.
# make it as a function def check_sth(): for i in range(5): for j in range(5): if j == 2 and i == 0: return check_sth() # Run the function when needed
Как показано выше, это решение выглядит более элегантно. Здесь нет переменных флагов, синтаксиса «try-except» или «for-else» и ненужной проверки условий.
Кроме того, «Turn Predicate Loops into Predicate Functions» — это хорошая практика написания кода, введенная командой компилятора LLVM.
Функции в Python очень гибкие. Мы можем легко определять вложенные функции или замыкания. Поэтому, если вложенные циклы будут использоваться только один раз и в пределах функции, мы можем просто определить их внутри этой функции:
def out_func(): # do something def check_sth(): for i in range(5): for j in range(5): if j == 2 and i == 0: return # do something check_sth() # Run the function when needed # do something
Вывод: Избегайте вложенных циклов
Если не существует элегантных решений для выхода из вложенных циклов, почему бы не избегать написания вложенных циклов?
Используя некоторые вспомогательные функции, мы действительно можем избежать вложенных циклов:
# Avoid nested loops import itertools for i, j in itertools.product(range(5), range(5)): if j == 2 and i == 0: break
Как показано выше, наш предыдущий пример может избежать вложенных циклов с помощью функции itertools.product. Это простой способ получить декартово произведение входных итераций.
К сожалению, этот способ не позволяет избежать всех вложенных циклов. Например, если нам нужно обрабатывать бесконечные потоки данных в наших циклах, он не поможет. Но это все равно хорошая идея, чтобы избежать вложенных циклов и улучшить читабельность наших программ.
Спасибо за прочтение! Какой из способов вы считаете самым полезным? Пишите в комментариях!
Еще больше примеров использования Python и Machine Learning в современных сервисах можно посмотреть в моем телеграм канале. Я пишу про разработку, ML, стартапы и релокацию в UK для IT специалистов.
- Python
- Программирование
- Алгоритмы
- Машинное обучение
- Искусственный интеллект
5 способов выйти из вложенного цикла в Python
Все мы знаем, что Python — довольно элегантный язык программирования, но, увы, у всех есть свои слабые стороны. Иногда Python выглядит не так аккуратно, как ему следовало бы. К примеру, нам нужно выйти из вложенного цикла как на примере ниже:
for a in list_a:
for b in list_b:
if condition(a,b):
break
Ключевое слово break позволяет выйти только из внутреннего цикла. Но можно ли напрямую сразу выйти из двух вложенных циклов? Есть ли для этого какие-нибудь ключевые слова или уловки? К сожалению, в Python нет встроенных средств для выполнения нужной операции.
Конечно, сравнивать языки друг с другом не стоит, но вот в PHP такое действие довольно просто можно провернуть:
foreach ($a_list as $a)
foreach ($b_list as $b)
if (condition($a, $b))
break 2; //break out of 2 loops
>
>
>
В PHP ключевое слово break принимает число в качестве аргумента, которое определяет, из скольки вложенных циклов нужно выйти. Значением по умолчанию установлено 1, что как раз позволяет выйти из крайнего цикла. Это довольно лаконичное и разумное решение, PHP выглядит привлекательнее с точки зрения написания кода.
Правда, это не значит, что всем пора бежать изучать PHP. Python все-таки очень гибкий язык, так что того же результата можно достичь многими другими способами.
В статье представлено 5 способов выхода из вложенного цикла в Python. В конце статьи также указано, как можно избежать проблемы вложенности в циклах.
1. Переменная-флаг
Первое решение довольно простое и эффективное. Чтобы выйти из цикла, надо объявить переменную и использовать ее как flag . Рассмотрим решение на примере ниже:
# добавьте переменную-флаг
break_out_flag = False
for i in range(5):
for j in range(5):
if j == 2 and i == 0:
break_out_flag = True
break
if break_out_flag:
break
Переменная break_out_flag выступает в качестве пометки, чтобы показать программе, когда следует выходить из внешнего цикла. Работает, но выглядит не очень красиво, так как приходится создавать новую переменную только ради решения такой маленькой проблемы. Можно обойтись и без этого. Рассмотрим другие варианты.
2. Вызов исключения
Если мы не можем использовать ключевое слово break как положено, почему бы тогда не выразить его действие другим способом? В Python существует возможность обработки исключений, поэтому из вложенного цикла можно выйти таким образом:
# вызовите исключение
try:
for i in range(5):
for j in range(5):
if j == 2 and i == 0:
raise StopIteration
except StopIteration:
pass
Код выше показывает, что break можно выразить как исключение и таким образом выйти из цикла.
3. Повторная проверка условия
Поскольку выполнение одного условия приводит к прерыванию цикла, проверка того же условия также кажется приемлемым решением. Вот как это выглядит:
# проверьте то же условие второй раз
for i in range(5):
for j in range(5):
if j == 2 and i == 0:
break
if j == 2 and i == 0:
break
Этот способ выполняет свою задачу, но выглядит он не очень эффективно, ведь проверять одно и то же условие много раз займет много времени и ресурсов.
4. Конструкция for-else
В Python есть особая конструкция for-else . Она не очень популярна, а некоторые совсем о ней не знают. Обычно, если пишут else , то только после if . А вот когда дело доходит до выхода из вложенных циклов, то такой необычный синтаксис может помочь в решении задачи:
# используйте конструкцию For-Else
for i in range(5):
for j in range(5):
if j == 2 and i == 0:
break
else: # можно вызывать, только если во внутреннем цикле нет break
continue
break
Этот метод берет все лучшее от синтаксиса for-else , так как код в блоке else сработает только в том случае, если внутренний цикл закончится без выхода. Если вы еще не знакомы с конструкцией for-else , то ознакомьтесь с кодом ниже — это конструкция, которая объясняет поведение конструкции:
# то же самое, что и конструкция for-else
for i in range(5):
for j in range(5):
if j == 2 and i == 0:
break
if not (j == 2 and i == 0):
continue
break
Если вкратце, то этот способ работает, но требует использования необычного синтаксиса.
5. Дополнительная функция
Если поместить вложенный цикл в функцию, то проблема выхода из цикла решается довольно просто, ведь вместо break можно использовать уже return .
# напишите для этого функцию
def check_sth():
for i in range(5):
for j in range(5):
if j == 2 and i == 0:
return
check_sth() # запустите функцию, где нужно
Это решение выглядит более понятно, тут нет переменных-флагов, нет try-except , for-else и ненужных проверок условий. Функции в Python настраиваются очень гибко, так что если вложенный цикл будет присутствовать по одному разу в каждой функции, то можно вызвать ее сразу во внешней функции:
def out_func():
# какой-то код
def check_sth():
for i in range(5):
for j in range(5):
if j == 2 and i == 0:
return
# какой-то код
check_sth() # запуск функции
# какой-то код
Правда, создание вложенной функции для двух циклов тоже выглядит не особо разумно.
Cовет: избегайте вложенных циклов
Но на деле, если не существует действительно удобных решений для выхода из вложенных циклов, тогда почему бы не постараться избегать их? Применяя вспомогательную функцию, можно избежать вложенных циклов:
# как избежать вложенных циклов
import itertools
for i, j in itertools.product(range(5), range(5)):
if j == 2 and i == 0:
break
Этот пример показывает, как с помощью функции itertools.product() можно обойтись без вложенности. Это простой способ вычисления декартова произведения на основе входных итераций. К несчастью, этим методом не получится избежать любых вложенных циклов. К примеру, он не сработает, если вам необходимо будет обработать бесконечные потоки данных в циклах.
Перед тем как функция itertools.product() начнет свою работу, ей необходимо получить на вход все переменные, сохраняя в памяти массивы значений для генерации результата. Таким образом, функция полезна только при конечном количестве входных данных. И всё же лучше следовать совету не прибегать к вложенным циклам, ведь это улучшает читаемость кода.
Заключение
У нас есть как минимум 5 возможных путей выхода из вложенных циклов в Python. Ни один из них не является настолько же удобным, как в PHP, но, по крайней мере, они все же существуют. К счастью, нам не обязательно использовать вложенные циклы, так как мы можем преобразовать их в простые циклы благодаря функции itertools.product() .
- Python для начинающих: all, any, zip, enumerate, filter, map
- Жажда скорости: Python с расширениями С
- Асинхронная многопоточность в Python
Выход из нескольких циклов в Python
В процессе написания кода на Python, часто возникает необходимость использовать несколько вложенных циклов. Иногда возникает ситуация, когда требуется прервать все эти циклы сразу. Но, к сожалению, в Python нет прямой команды для выхода из нескольких циклов одновременно.
Рассмотрим следующий пример:
while True: while True: # какой-то код if условие: break # хочу выйти из обоих циклов, но выйду только из внутреннего # еще код
В данном случае, команда break прервет только внутренний цикл, а внешний цикл продолжится. Эта особенность работы break в Python может привести к нежелательному поведению программы.
Однако, существуют способы обойти эту особенность языка и прервать все вложенные циклы сразу.
Использование исключений
Один из способов — использование исключений. Можно определить свое исключение, которое будет сигналом для выхода из всех циклов.
class BreakLoops(Exception): pass try: while True: while True: # какой-то код if условие: raise BreakLoops except BreakLoops: pass
Здесь мы создаем свой класс исключений BreakLoops , который наследуется от класса Exception . При выполнении условия мы генерируем исключение BreakLoops , которое прерывает все циклы.
Использование флага
Еще один вариант — использование флага. Флаг — это переменная, которая сигнализирует о выполнении или невыполнении определенного условия.
break_flag = False while True: while True: # какой-то код if условие: break_flag = True break if break_flag: break
Если условие истинно, мы устанавливаем флаг в True и прерываем внутренний цикл с помощью break . Затем во внешнем цикле проверяем значение флага, и если оно True , прерываем и внешний цикл.
Оба этих метода позволяют выйти из всех вложенных циклов одновременно. Выбор между ними зависит от конкретной задачи и личных предпочтений программиста.
