[python] Python : 외부 루프에서 다음 반복으로 계속

파이썬의 외부 루프에서 다음 반복을 계속할 수있는 내장 방법이 있는지 알고 싶었습니다. 예를 들어 다음 코드를 고려하십시오.

for ii in range(200):
    for jj in range(200, 400):
        ...block0...
        if something:
            continue
    ...block1...

이 continue 문이 jj 루프를 종료하고 ii 루프의 다음 항목으로 이동하기를 원합니다. 다른 방법으로 (플래그 변수를 설정하여)이 논리를 구현할 수 있지만 쉬운 방법이 있습니까? 아니면 너무 많이 요구하는 것과 같은가요?



답변

for i in ...:
    for j in ...:
        for k in ...:
            if something:
                # continue loop i

일반적으로 여러 레벨의 루핑이있을 때 break 가없는 경우 (현재 루프 바로 위가 아닌 상위 루프 중 하나를 계속하려는 경우) 다음 중 하나를 수행 할 수 있습니다.

탈출하려는 루프를 함수로 리팩토링

def inner():
    for j in ...:
        for k in ...:
            if something:
                return


for i in ...:
    inner()

단점은 이전에 범위에 있던 일부 변수를 해당 새 함수에 전달해야 할 수도 있다는 것입니다. 매개 변수로 매개 변수를 전달하고 객체에 인스턴스 변수를 만들거나 (이 함수에 맞는 새 객체를 만드는 경우) 전역 변수, 단일 톤 (ehm, ehm)을 지정할 수 있습니다.

또는 inner중첩 함수로 정의 하고 필요한 것을 캡처하도록 할 수 있습니다 (느려질 수 있습니까?).

for i in ...:
    def inner():
        for j in ...:
            for k in ...:
                if something:
                    return
    inner()

예외 사용

철학적으로, 이것은 예외적 인 경우이며, 필요한 경우 구조화 된 프로그래밍 빌딩 블록을 통해 프로그램 흐름을 깨뜨립니다.

장점은 단일 코드를 여러 부분으로 나눌 필요가 없다는 것입니다. 파이썬으로 작성하는 동안 디자인하는 계산의 종류라면 좋습니다. 이 초기 시점에 추상화를 도입하면 속도가 느려질 수 있습니다.

이 접근법의 나쁜 점은 통역사 / 컴파일러 작성자는 일반적으로 예외가 예외적이라고 가정하고 그에 따라 최적화한다는 것입니다.

class ContinueI(Exception):
    pass


continue_i = ContinueI()

for i in ...:
    try:
        for j in ...:
            for k in ...:
                if something:
                    raise continue_i
    except ContinueI:
        continue

이를 위해 특별한 예외 클래스를 생성하여 실수로 다른 예외를 침묵시킬 위험이 없도록하십시오.

완전히 다른 것

나는 여전히 다른 해결책이 있다고 확신합니다.


답변

for ii in range(200):
    for jj in range(200, 400):
        ...block0...
        if something:
            break
    else:
        ...block1...

Break 내부 루프가 중단되고 block1이 실행되지 않습니다 (내부 루프가 정상적으로 종료 된 경우에만 실행 됨).


답변

다른 언어에서는 루프에 레이블을 지정하고 레이블이 지정된 루프에서 벗어날 수 있습니다. Python Enhancement Proposal (PEP) 3136은 이것을 Python에 추가 할 것을 제안 했지만 Guido는 거부했습니다 .

그러나이 기능을 요구하기에 너무 복잡한 코드는 매우 드물기 때문에 거부합니다. 대부분의 경우 깨끗한 코드를 생성하는 기존 해결 방법이 있습니다 (예 : ‘return’사용). 코드의 선명도가 리팩토링으로 인해 리턴을 사용할 수있는 드문 실제 사례가 있지만 두 가지 문제로 상쇄됩니다.

  1. 언어에 복잡성이 영구적으로 추가되었습니다. 이것은 모든 Python 구현뿐만 아니라 모든 소스 분석 도구와 언어에 대한 모든 문서에 영향을 미칩니다.

  2. 이 기능이 올바르게 사용되는 것보다 더 많이 남용 될 것이라는 기대는 코드 선명도의 감소로 이어졌습니다 (이후로 작성된 모든 Python 코드에서 측정 됨). 게으른 프로그래머는 어디에나 있으며, 그것을 알기 전에는 이해할 수없는 코드를 손에 넣을 수 있습니다.

그래서 그것이 당신이 바라는 것이면 운이 좋지 않지만 거기에 좋은 옵션이 있기 때문에 다른 대답 중 하나를보십시오.


답변

나는 당신이 이런 식으로 할 수 있다고 생각합니다 :

for ii in range(200):
    restart = False
    for jj in range(200, 400):
        ...block0...
        if something:
            restart = True
            break
    if restart:
        continue
    ...block1...


답변

이 작업을 수행하는 가장 쉬운 방법 중 하나는 “continue”를 “break”문으로 바꾸는 것입니다.

for ii in range(200):
 for jj in range(200, 400):
    ...block0...
    if something:
        break
 ...block1...       

예를 들어 다음은 정확히 어떻게 진행되는지 확인하는 쉬운 코드입니다.

for i in range(10):
    print("doing outer loop")
    print("i=",i)
    for p in range(10):
        print("doing inner loop")
        print("p=",p)
        if p==3:
            print("breaking from inner loop")
            break
    print("doing some code in outer loop")


답변

이런 종류의 문제를 처리하는 또 다른 방법은 Exception ()을 사용하는 것입니다.

for ii in range(200):
    try:
        for jj in range(200, 400):
            ...block0...
            if something:
                raise Exception()
    except Exception:
        continue
    ...block1...

예를 들면 다음과 같습니다.

for n in range(1,4):
    for m in range(1,4):
        print n,'-',m

결과:

    1-1
    1-2
    1-3
    2-1
    2-2
    2-3
    3-1
    3-2
    3-3

m = 3 인 경우 m 루프에서 외부 n 루프로 점프한다고 가정합니다.

for n in range(1,4):
    try:
        for m in range(1,4):
            if m == 3:
                raise Exception()
            print n,'-',m
    except Exception:
        continue

결과:

    1-1
    1-2
    2-1
    2-2
    3-1
    3-2

참조 링크 : http://www.programming-idioms.org/idiom/42/continue-outer-loop/1264/python


답변

무언가를 찾은 다음 내부 반복을 중지하려고합니다. 플래그 시스템을 사용합니다.

for l in f:
    flag = True
    for e in r:
        if flag==False:continue
        if somecondition:
            do_something()
            flag=False