for row in b:
for drug in drug_input:
for brand in brand_names[drug]:
из третьего цикла, как мне выйти из текущего цикла и перейти к следующему значению for row in b:
?
for row in b:
for drug in drug_input:
for brand in brand_names[drug]:
из третьего цикла, как мне выйти из текущего цикла и перейти к следующему значению for row in b:
?
Этот метод использует логическое значение, чтобы убедиться, что все еще выполнено:
done = False
for x in xs:
for y in ys:
if bad:
done = True
break
if done:
break
Это будет continue
, если перерыв не использовался. else
будет пропущен, если произошел разрыв, поэтому он увидит следующий break
. Этот подход имеет преимущество в том, что ему не нужно использовать переменную, но может быть труднее прочитать некоторые.
for x in xs:
for y in ys:
if bad:
break
else:
continue
break
for row in b:
more_drugs = True
for drug in drug_input:
for brand in brand_names[drug]:
if something:
more_drugs = False
break
if not more_drugs:
break
Python не имеет структуры управления для разрыва с двух петель одновременно, поэтому вам нужно сделать что-то ручное, как это.
Если у вас есть три уровня цикла в одном методе, вам, вероятно, нужно переосмыслить свой дизайн.
all
и any
, чтобы избежать написания явных циклов.Выполнение любого из этих действий должно означать, что у вас больше нет этой проблемы.
Обработка исключений превосходит значения переменных по всему месту IMO
for row in b:
for drug in drug_input:
try:
for brand in brand_names[drug]:
if some_condition:
raise StopIteration
except StopIteration:
break
Я бы рассмотрел возможность размещения двух внутренних циклов в функции и используя return. Вероятно, переосмыслив то, что вы делаете, и как это дает лучшую альтернативу этому.
Не могли бы вы дать свой текущий псевдокод, ввод и вывод, чтобы мы могли попытаться устранить необходимость перерыва на первом месте? Нам нужно увидеть, где используются переменные цикла или еще лучше, какова цель обработки.
Последний PEP. Я вижу, что запрос этой функции 3136 (и был отклонен): http://mail.python.org/pipermail/python-3000/2007-July/008663.html
Ближайшая и самая чистая вещь, которую я мог видеть в том, что вы хотите сделать, будет делать следующее (и, поскольку даже имена типов ограничены, вы можете объявить LocalBreak внутри функции, которая вам нужна):
class LocalBreak(Exception): pass
try:
for i in ...:
for h in ...:
for j in ...:
if should_break(j):
raise LocalBreak()
except LocalBreak:
pass
Непроверенные:
inner_termination=False
for row in b:
for drug in drug_input:
for brand in brand_names[drug]:
<blah>
if break_condition:
inner_termination=True
break
<blah>
if inner_termination:
inner_termination=False
break
for row in b:
ok = True
for drug in drug_input:
if not ok:
break;
for brand in brand_names[drug]:
if not ok:
break
if whatever:
ok = False
try
/except
/raise
, как предложено в комментарии @gddc, является одной из возможностей. Другим является "завершение" двух вложенных циклов в один:
for row in b:
for brand in (b for d in drug_input for b in brand_names[d]):
...
теперь a break
из вложенного цикла for brand
вернется к уровню внешнего цикла for row
. Конечно, это работает только тогда, когда код, который здесь заменен на ...
, не должен видеть имя drug
, связанное с рассматриваемым в настоящее время препаратом. Это дело для вас?
for a in aa:
for b in bb:
for c in cc:
if c == a[b]:
break
else:
continue
break
Python поддерживает инструкции for...else
. Блок else
оценивается, если внутренний break
не запускается.
Если у вас слишком много встроенных циклов, возможно, настало время для рефакторинга. В этом случае я считаю, что лучший рефактор должен переместить ваши циклы в функцию и использовать оператор return
. Это приведет к выходу из любого числа циклов. Например:
def example(self, drug_input):
ok = False
for x in drug_input["names"]:
for y in range(drug_input["number_of_drugs"]):
for z in drug_input["list_of_drugs"]:
# do stuff
if ok:
return drug_costs
Теперь, возможно, переформулировать вашу логику, как это сложно, но я уверен, что рефакторинг поможет другим способом.