Учитывая следующий код (это не работает):
while True:
#snip: print out current state
while True:
ok = get_input("Is this ok? (y/n)")
if ok.lower() == "y": break 2 #this doesn't work :(
if ok.lower() == "n": break
#do more processing with menus and stuff
Есть ли способ сделать эту работу? Или я должен сделать одну проверку, чтобы выйти из цикла ввода, а затем другую, более ограниченную, проверить во внешнем цикле, чтобы разорвать все вместе, если пользователь удовлетворен?
python
nested-loops
break
control-flow
Мэтью Шарли
источник
источник
goto
если вы глубокоОтветы:
Моим первым инстинктом было бы реорганизовать вложенный цикл в функцию и использовать ее
return
для разрыва.источник
return
это правильный подход. И причина в том, что, согласно дзену Python , «квартира лучше вложенной». Здесь у нас есть три уровня вложенности, и если это начинает мешать, пришло время уменьшить вложенность или, по крайней мере, извлечь целое вложение в свою собственную функцию.Вот еще один короткий подход. Недостатком является то, что вы можете разорвать только внешний цикл, но иногда это именно то, что вы хотите.
Здесь используется конструкция for / else, объясненная в: Почему Python использует «else» после циклов for и while?
Основная идея: только кажется, что внешний цикл всегда прерывается. Но если внутренний цикл не прерывается, внешний цикл тоже не будет.
continue
Заявление магия здесь. Это в пункте для другого. По определению это происходит, если нет внутреннего разрыва. В этой ситуацииcontinue
аккуратно обходит внешний разрыв.источник
PEP 3136 предлагает помеченный перерыв / продолжение. Гвидо отверг это, потому что «код, настолько сложный, чтобы требовать эту функцию, очень редок». Однако в PEP упоминаются некоторые обходные пути (например, метод исключения), в то время как Гвидо считает, что рефакторинг для использования return будет проще в большинстве случаев.
источник
return
- это, как правило, путь, я видел довольно много случаев, когда простое сжатоеbreak 2
утверждение ' ' имело бы столько смысла. Кроме того, рефакторинг /return
не работает так же дляcontinue
. В этих случаях будет проще следовать числовому разбиению и продолжению, и оно будет менее загромождено, чем рефакторинг крошечной функции, вызывая исключения или замысловатую логику, включающую установку флага для разбиения на каждом уровне гнезда. Обидно, Гвидо это отверг.break; break
было бы здорово.break
все циклы. Глупый.Во-первых, обычная логика полезна.
Если по какой-либо причине условия прекращения не могут быть разработаны, исключения являются запасным планом.
Для этого конкретного примера исключение может не потребоваться.
С другой стороны, у нас часто есть опции «Y», «N» и «Q» в символьных приложениях. Для опции «Q» мы хотим немедленный выход. Это более исключительно.
источник
done
). (2) поднятие исключения. Объединение их в одно решение просто делает его сложным. Для будущих читателей: ЛИБО используйте все участвующие строкиdone
, ИЛИ определяйтеGetOutOfLoop(Exception)
и повышайте / кроме этого.Exception
конструктору (напримерraise Exception('bla bla bla')
) допустимы как в Python 2, так и в Python 3. Первое предпочтительнее в этом случае, потому что мы не хотим нашexcept
блок для перехвата всех исключений, но только специального исключения, которое мы используем для выхода из цикла. Если мы будем действовать так, как вы предлагаете, а затем ошибка в нашем коде вызовет непредвиденное исключение, то это будет ошибочно восприниматься так же, как преднамеренный выход из цикла.Я склонен согласиться с тем, что рефакторинг в функцию обычно является наилучшим подходом для такого рода ситуаций, но для случаев, когда вам действительно нужно вырваться из вложенных циклов, вот интересный вариант подхода, вызывающего исключения, который описал @ S.Lott. Он использует
with
оператор Python, чтобы повышение исключений выглядело немного лучше. Определите новый менеджер контекста (вы должны сделать это только один раз) с:Теперь вы можете использовать этот менеджер контекста следующим образом:
Преимущества: (1) он немного чище (без явного блока try-кроме), и (2) вы получаете пользовательский
Exception
подкласс для каждого использованияnested_break
; нет необходимостиException
каждый раз объявлять свой собственный подкласс.источник
Во-первых, вы также можете подумать о том, чтобы сделать процесс получения и проверки входных данных функцией; в рамках этой функции, вы можете просто вернуть значение , если его правильно, и держать спиннинг в то время как петли , если нет. По сути, это устраняет проблему, которую вы решили, и обычно может применяться в более общем случае (разрыв нескольких циклов). Если вам абсолютно необходимо сохранить эту структуру в своем коде, и вы действительно не хотите иметь дело с булевыми значениями бухгалтерии ...
Вы также можете использовать goto следующим образом (используя модуль April Fools отсюда ):
Я знаю, я знаю, «ты не должен использовать goto» и все такое, но это хорошо работает в странных случаях, подобных этому.
источник
Введите новую переменную, которую вы будете использовать как «прерыватель цикла». Сначала присвойте ему что-нибудь (False, 0 и т. Д.), А затем, во внешнем цикле, перед тем как выйти из него, измените значение на что-то другое (True, 1, ...). Как только цикл выйдет, сделайте родительский цикл для проверки этого значения. Позвольте мне продемонстрировать:
Если у вас бесконечный цикл, это единственный выход; для других циклов выполнение действительно намного быстрее. Это также работает, если у вас много вложенных циклов. Вы можете выйти из всех, или только несколько. Безграничные возможности! Надеюсь, это помогло!
источник
Чтобы разорвать несколько вложенных циклов без рефакторинга в функцию, используйте «симулированный оператор goto» со встроенным исключением StopItered :
Посмотрите это обсуждение использования операторов goto для разрыва вложенных циклов.
источник
или что-то типа того. Вы можете установить переменную во внутреннем цикле и проверить ее во внешнем цикле сразу после выхода из внутреннего цикла, прервав при необходимости. Мне нравится метод GOTO, при условии, что вы не возражаете против использования модуля первоапрельской шутки - он не Pythonic, но он имеет смысл.
источник
Это не самый красивый способ сделать это, но, на мой взгляд, это лучший способ.
Я почти уверен, что и здесь вы можете что-то придумать, используя рекурсию, но я не знаю, подходит ли вам этот вариант.
источник
И почему бы не продолжать цикл, если выполняются два условия? Я думаю, что это более питонический способ:
Не так ли?
Всего наилучшего.
источник
while dejaVu:
? В любом случае вы устанавливаете его в true.True
условиях пропустить две петли, но одной достаточно.if not dejaVu: break
внизу и, таким образом, выйти из основного цикла? Я думаю, что решение наиболее близко к тому, что было задано. +1Разложите логику вашего цикла в итератор, который возвращает переменные цикла и возвращает, когда все готово - вот простое, которое выкладывает изображения в строки / столбцы до тех пор, пока у нас не будет изображений или нет мест для их размещения:
Это имеет преимущество разделения сложной логики цикла и обработки ...
источник
В этом случае, как отмечают и другие, функциональная декомпозиция - это путь. Код в Python 3:
источник
В
while ... else
структуре Python есть скрытый трюк, который можно использовать для имитации двойного разрыва без особых изменений / дополнений кода. По сути, еслиwhile
условие ложно,else
блок срабатывает. Ни исключений,continue
ниbreak
триггераelse
блока. Для получения дополнительной информации см. Ответы на « Предложение Else для Python while Statement » или документацию Python для while (v2.7) .Единственным недостатком является то, что вам нужно переместить условие двойного разбиения в
while
условие (или добавить переменную flag). Вариации этого существуют и дляfor
цикла, гдеelse
блок запускается после завершения цикла.источник
How to break out of multiple loops in Python?
и ответ должен был быть "Это не работает, попробуйте что-нибудь еще". Я знаю, что это исправляет точный приведенный пример ОП, но не отвечает на их вопрос.Другой способ сократить вашу итерацию до одноуровневого цикла - использовать генераторы, как также указано в ссылке на Python.
Вы можете масштабировать его до любого количества уровней для цикла
Недостатком является то, что вы больше не можете пробить только один уровень. Это все или ничего.
Другим недостатком является то, что он не работает с циклом while. Первоначально я хотел опубликовать этот ответ на Python - `break` из всех циклов, но, к сожалению, он закрыт как дубликат этого
источник
Моя причина приехать сюда в том, что у меня был внешний цикл и внутренний цикл, например, так:
Как видите, на самом деле он не перейдет к следующему x, а вместо этого перейдет к следующему y.
то, что я нашел, чтобы решить эту проблему, это просто дважды запустить массив:
Я знаю, что это был конкретный случай вопроса ОП, но я публикую его в надежде, что он поможет кому-то по-другому взглянуть на свою проблему, оставив при этом все просто.
источник
break
вместо того,continue
чтобы делать то, что вы хотите, не так ли? :-)Попробуйте использовать бесконечный генератор.
источник
Используя функцию:
Попробуйте запустить приведенные выше коды, также закомментировав их
return
.Без использования какой-либо функции:
Теперь запустите приведенные выше коды как есть, а затем попробуйте запустить, закомментировав каждую строку, содержащую по
break
одной, снизу.источник
Простой способ превратить несколько циклов в один разрывный цикл - это использовать
numpy.ndindex
Вы должны индексировать свои объекты, в отличие от возможности явно перебирать значения, но, по крайней мере, в простых случаях это кажется примерно в 2-20 раз проще, чем большинство предлагаемых ответов.
источник
источник
вероятно, подойдет маленький трюк, как показано ниже, если не предпочитаете рефакториал в функцию
добавлена 1 переменная break_level для управления условием цикла while
источник
Вы можете определить переменную (например, break_statement ), а затем изменить ее на другое значение при возникновении условия двух разрывов и использовать его в операторе if для выхода из второго цикла.
источник
Я хотел бы напомнить вам, что функции в Python могут быть созданы прямо в середине кода и могут прозрачно обращаться к окружающим переменным для чтения и с помощью
nonlocal
илиglobal
декларации для записи.Таким образом, вы можете использовать функцию в качестве «разрушаемой структуры управления», определяя место, куда вы хотите вернуться:
источник
Решения в 2 пути
С примером: эти две матрицы равны / одинаковы?
matrix1 и matrix2 имеют одинаковый размер, n, 2 размерных матрицы.
Первое решение , без функции
Второе решение , с функцией
Это окончательное решение по моему делу
Хорошего дня!
источник
источник
Надеюсь, это поможет:
источник
Вот реализация, которая, кажется, работает:
Единственным недостатком является то, что вы должны определить
break_
перед циклами.источник
Кредит Вивеку Нагараджану, программисту с 1987 года
Используя функцию
Используя флаг
источник
Похожий на предыдущий, но более компактный. (Логические числа просто числа)
источник
Поскольку этот вопрос стал стандартным вопросом для разбиения на определенный цикл, я хотел бы дать свой ответ с примером, используя
Exception
.Хотя в конструкции с многократным циклом не существует метки с именем разрыв цикла, мы можем использовать определяемые пользователем исключения для разбиения на определенный цикл по нашему выбору. Рассмотрим следующий пример, где мы будем печатать все числа до 4 цифр в системе нумерации base-6:
Когда мы печатаем выходные данные, мы никогда не получим никакого значения, единичное место которого равно 4. В этом случае мы не отрываемся ни от одного цикла, который
BreakLoop(4)
возникает и захватывается в том же цикле. Точно так же, всякий раз, когда в десятке есть 3, мы используем третий циклBreakLoop(3)
. Когда сто мест имеет 5, мы входим во второй цикл,BreakLoop(2)
а когда в тысяче мест 2, мы в первый циклBreakLoop(1)
.Короче говоря, поднимите свое Исключение (встроенное или определенное пользователем) во внутренних циклах и перехватите его в цикле, откуда вы хотите возобновить управление. Если вы хотите выйти из всех циклов, поймайте исключение за пределами всех циклов. (Я не показал этот случай в примере).
источник