Именование циклов в Python

Я недавно прочитал этот вопрос, который имел решение о маркировке циклов в Java.

Мне интересно, существует ли такая система именования петель в Python. Я был в ситуации несколько раз, когда мне нужно вырваться из внешнего for петля изнутри for петля. Обычно я решаю эту проблему, помещая внутренний цикл в функцию, которая возвращает (среди прочего) логическое значение, которое используется как условие прерывания. Но маркировка циклов для взлома кажется намного проще, и я хотел бы попробовать это, если такая функциональность существует в Python

Кто-нибудь знает, если это так?

4 ответа

Решение

Было предложение включить именованные циклы в python PEP3136, однако оно было отклонено с объяснением здесь. Отказ был в основном из-за редкого числа обстоятельств, когда читаемость кода была бы улучшена путем включения этой конструкции.

Вот способ разбить несколько вложенных блоков с помощью диспетчера контекста:

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

Хотя есть причины для включения named loop в языковую конструкцию, вы можете легко избежать этого в 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
>>> 

Я решаю эту проблему, помещая внутренний цикл в функцию, которая возвращает (среди прочего) логическое значение, которое используется как условие прерывания.

Я думаю, вы должны попробовать это. Это очень питонно, просто и читабельно.

Нету.

В зависимости от того, что вы делаете, есть большая вероятность, что вы можете использовать что-то из itertools, чтобы сгладить ваши вложенные циклы for в один цикл for.

Другие вопросы по тегам