Именование циклов в Python
Недавно я прочитал этот вопрос, в котором было решение о цикле маркировки в Java.
Мне интересно, существует ли такая система с именованием циклов в Python. Я был в ситуации несколько раз, когда мне нужно вырваться из внешнего цикла for
из внутреннего цикла for
. Обычно я решаю эту проблему, помещая внутренний цикл в функцию, которая возвращает (среди прочего) логическое значение, которое используется как условие прерывания. Но метки меток для разбивки кажутся намного проще, и я хотел бы попробовать, если такая функциональность существует в python
Кто-нибудь знает, не делает ли это?
Ответы
Ответ 1
Было предложение включить именованные циклы в python PEP3136, однако оно было отклонено с объяснением здесь. Отказ был вызван главным образом из-за редкого числа обстоятельств, когда считываемость кода была бы улучшена путем включения этой конструкции.
Ответ 2
Несмотря на то, что есть причины включить именованный цикл в конструкцию языка, вы можете легко избежать его в python без потери удобочитаемости.
Реализация упомянутого примера в python
>>> try:
for i in xrange(0,5):
for j in xrange(0,6):
if i*j > 6:
print "Breaking"
raise StopIteration
print i," ",j
except StopIteration:
print "Done"
0 0
0 1
0 2
0 3
0 4
0 5
1 0
1 1
1 2
1 3
1 4
1 5
2 0
2 1
2 2
2 3
Breaking
Done
>>>
Я решаю эту проблему, помещая внутренний цикл в функцию, которая возвращает (среди прочего) логическое значение, которое используется как разрыв состояние.
Я думаю, вы должны попробовать это. Это очень pythonic, просто и читаемо.
Ответ 3
Здесь вы можете вырваться из нескольких вложенных блоков с помощью диспетчера контекстов:
import contextlib
@contextlib.contextmanager
def escapable():
class Escape(RuntimeError): pass
class Unblock(object):
def escape(self):
raise Escape()
try:
yield Unblock()
except Escape:
pass
Вы можете использовать его для выхода из нескольких циклов:
with escapable() as a:
for i in xrange(30):
for j in xrange(30):
if i * j > 6:
a.escape()
И вы можете даже их вложить:
with escapable() as a:
for i in xrange(30):
with escapable() as b:
for j in xrange(30):
if i * j == 12:
b.escape() # Break partway out
if i * j == 40:
a.escape() # Break all the way out
Ответ 4
Неа.
В зависимости от того, что вы делаете, есть хорошие шансы, что вы можете использовать что-то из itertools, чтобы сгладить ваши вложенные петли в один цикл for.