[Python] 파이썬의 이중 for문 break하기 (중첩 loop 탈출)

hwhyeons·2024년 11월 7일

Python에서는 이중 for문에서 내부 for문을 바로 break하는 방법이 다른 언어와 다른 부분들이 있습니다.

C,C++의 언어는 goto문을 이용해서 중첩for문을 바로 종료할 수 있고,
Java, JavaScript 등은 레이블을 이용해서 쉽게 반복문을 탈출할 수 있습니다.

자바를 예로 들면

lb:
for (int i = 0; i < 10; i++) {
    for (int j = 0; j < 10; j++) {
        System.out.println("i = " + i + " j = " + j);
        if (i == 5 && j == 5) {
            System.out.println("중첩 반복문 탈출");
            break lb;
        }
    }
}

하지만 파이썬은 이를 제공하지 않습니다.




왜 Python은 중첩 for문 탈출을 제공하지 않는가?

굳이 왜 이중for문 등을 쉽게 탈출하기위해 레이블 방식을 제공하지 않는지
궁금해서 구글링 해봤습니다.

실제로 PEP에 아래와같은 제안이 있었습니다.
https://peps.python.org/pep-3136/

이에대한 파이썬 창시자 귀도 반 로섬의 답변은
https://mail.python.org/pipermail/python-3000/2007-July/008663.html
에서 확인할 수 있습니다.

답변을 요약하면
1. return문을 이용해서 종료할 수 있음
2. 언어가 복잡해진다. 기존 분석도구 및 언어 문서화에도 영향을 미친다
3. 해당 기능이 남용될 수 있다

정도입니다.




Python의 중첩 Loop를 탈출하는 여러가지 방법


방법 1. 중첩 loop를 함수 하나로 만들고 return한다

위 Java로 작성한 예시를 파이썬 코드로 동일한 동작을 구현해보겠습니다.

def func():
    for i in range(10):
        for j in range(10):
            print(f"i = {i} j = {j}")
            if i == 5 and j == 5:
                print("중첩 반복문 탈출")
                return
    
if __name__ == '__main__':
    func()

이렇게 이중 for문을 하나의 함수로 만들고, return시에 해당 함수가 종료되는데, 그건 곧 이중 for loop의 탈출이됩니다.



방법 2. flag 변수를 만들어서 break

flag =False
for i in range(10):
    for j in range(10):
        print(f"i = {i} j = {j}")
        if i == 5 and j == 5:
            print("중첩 반복문 탈출")
            flag = True
            break
    if flag:
        break

바깥 for문 반복시에 flag를 체크해서, flag가 참이면 탈출하는 방법입니다.
저는 보통 이렇게 작성해왔던 것 같습니다.



방법 3. itertools.product()를 사용

파이썬이 아니면 시도해보고 싶지 않은 새로운 방법인 것 같습니다.
생각을 못해봤는데, 링크 답변에서 발견한 방법입니다.

from itertools import product
for i, j in product(range(10), range(10)):
    print(f"i = {i} j = {j}")
    if i == 5 and j == 5:
        print("중첩 반복문 탈출")
        break



방법 4. for else 구문

Python에서는 for-else 구문과 while-else 구문을 지원합니다.
for-else(while-else)의 else는 break로 종료되지 않으면 실행됩니다.
이를 역이용하면, 안쪽 for문이 break되면 바깥 for문을 continue하지 않는
방법으로 구현해볼 수 있습니다.

for i in range(10):
    for j in range(10):
        print(f"i = {i} j = {j}")
        if i == 5 and j == 5:
            print("중첩 반복문 탈출")
            break
    else:
        continue
    break



방법 5. generator 사용

def gen():
    for i in range(10):
        for j in range(10):
            yield (i, j)
            if i == 5 and j == 5:
                print("중첩 반복문 탈출")
                return

if __name__ == '__main__':
    g = gen()
    for i, j in g:
        print(f"i = {i} j = {j}")

간단한 중첩 루프가 아닌, 제네레이터를 사용해야하는 상황에서
잘 맞는 방법인 것 같습니다.
이 방법은 제네레이터를 이용한 for loop 탈출이라기보다는
파이썬에서 제네레이터, yield를 사용하는 방법에 가까운 것 같습니다.

0개의 댓글