Именование циклов в 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.