본문으로 건너뛰기

break와 continue

파이썬 목차반복레슨 21 / 59

목차

break는 반복을 그 자리에서 끝내고, continue는 이번 바퀴의 남은 줄을 건너뛰고 다음 바퀴로 갑니다. 둘 다 반복 안에서만 씁니다.

지금까지의 반복은 정해진 바퀴를 다 돌거나 조건이 거짓이 될 때까지 돌았습니다. 그런데 찾던 것을 찾았다면 남은 값을 더 볼 까닭이 없고, 어떤 값은 건너뛰고 싶을 때도 있습니다. 빈 줄이 올 때까지 묻기처럼 언제 끝날지 미리 모르는 반복도 있습니다. 이럴 때 덩어리 가운데서 반복의 흐름을 바꾸는 것이 break와 continue입니다.

10단계 중 1단계. 주문 기록 '커라커쿠'에서 라테('라')를 찾습니다. 찾으면 바로 멈춥니다.

1break — 찾으면 반복을 끝낸다

오늘 주문을 메뉴 첫 글자로 줄여 '커라커쿠'(커피·라테·커피·쿠키)로 적었습니다. 라테('라')를 판 적이 있는지 찾습니다. 찾는 일도 하위 목표 셋으로 나눕니다.

# 1. 깃발 내리기
found = False
# 2. 하나씩 보며 찾으면 올리고 멈추기
for ch in '커라커쿠':
    if ch == '라':
        found = True
        break
# 3. 깃발 보고 쓰기
print(found)
실행 결과
True
  • 1. 깃발 내리기: found를 False에 붙여 둡니다. 아직 찾지 못했다는 표시입니다.
  • 2. 하나씩 보며 찾으면 올리고 멈추기: 글자를 하나씩 꺼내 보다가 '라'를 만나면 found를 True에 붙이고(깃발 올리기) break로 반복을 끝냅니다.
  • 3. 깃발 보고 쓰기: 반복이 끝난 뒤 깃발을 보고 결과를 씁니다.

추적 표로 따라가면 break 뒤에는 남은 글자를 보지 않는 것이 드러납니다.

줄바뀐 이름값출력
2foundFalse
4ch'커'
5조건 ch == '라'False
4ch'라'
5조건 ch == '라'True
6foundTrue
7break — 반복 끝
9True

break는 감싸고 있는 반복을 끝냅니다. if 덩어리 안에 있어도 끝나는 것은 if가 아니라 바깥 for입니다. 그래서 셋째·넷째 글자 '커'와 '쿠'는 꺼내지 않습니다. found도 elif로 여러 갈래에서 본 깃발입니다. True·False 하나에 붙는 이름인데, 찾기에서는 처음에 False로 내려 두었다가 찾으면 True로 올립니다. 깃발은 한 번 올리면 다시 내리지 않습니다.

2continue — 이번 바퀴만 건너뛴다

아래 코드는 무엇을 찍을까요? 답을 정한 뒤 펼쳐 보세요.

for ch in '커라커':
    if ch == '라':
        continue
    print(ch)
실행 결과 보기
실행 결과
커
커

예상과 다르면 그곳이 배울 곳입니다. continue를 만나면 이번 바퀴의 남은 줄(4번 줄)을 건너뛰고 1번 줄로 돌아가 다음 글자를 꺼냅니다. 반복은 끝나지 않습니다. 그래서 '라'만 빼고 두 '커'가 찍힙니다.

continue는 '이 값이면 이번 바퀴는 여기까지'를 앞에서 정할 때 씁니다. 1절의 찾기를 continue로 쓰면 이렇습니다. 찾는 글자가 아니면 바로 다음 글자로 넘어가고, 찾는 글자일 때만 5~6번 줄에 닿습니다.

found = False
for ch in '커라커쿠':
    if ch != '라':
        continue
    found = True
    break
print(found)
실행 결과
True

결과는 1절과 같습니다. 찾았을 때 할 일(5~6번 줄)을 한 단계 덜 들여 쓸 수 있습니다.

3끝을 모를 때 — while True와 break

조건 자리에 True를 두면 조건이 늘 참이라 반복이 스스로 끝나지 않습니다. 끝낼지는 덩어리 안에서 break로 정합니다. 값을 물어본 다음에야 끝낼지 알 수 있을 때 이렇게 씁니다. 메뉴를 묻다가 빈 줄(아무것도 치지 않고 Enter)이 오면 끝내는 코드입니다. 커피와 라테를 넣고 빈 줄로 끝내면 이렇게 찍힙니다.

while True:
    text = input('메뉴: ')
    if text == '':
        break
    print(text, '주문')
print('주문 끝')넣는 값커피라테빈 줄
실행 결과
메뉴: 커피
커피 주문
메뉴: 라테
라테 주문
메뉴: 
주문 끝

빈 줄을 넣으면 input()은 빈 문자열 ''을 돌려줍니다. 3번 줄의 조건이 True가 되어 4번 줄의 break가 반복을 끝내고, 6번 줄로 갑니다. 이 단원 끝의 작은 계산기가 이 꼴로 가격을 받습니다.

예제

찾지 못하면 깃발은 그대로

녹차('녹')를 찾습니다. 이번에는 3번 하위 목표에서 깃발을 보고 if로 문장을 골라 씁니다.

found = False
for ch in '커라커쿠':
    if ch == '녹':
        found = True
        break
if found:
    print('녹차 주문 있음')
else:
    print('녹차 주문 없음')
실행 결과
녹차 주문 없음

'녹'이 없어서 break를 만나지 않고 네 글자를 다 본 뒤 반복이 끝납니다. 깃발은 1번 줄에서 내린 그대로 False이고, 8번 줄의 else 쪽이 실행됩니다.

break를 반복 밖에서 쓰면

found = True
if found:
    break
실행 결과
  File "main.py", line 3    break    ^^^^^SyntaxError: 'break' outside loop

맨 아래 줄부터 읽습니다. SyntaxError는 문법 오류이고, 'break가 반복 밖에 있다(outside loop)'는 뜻입니다. break는 반복을 끝내는 말이라 for나 while 덩어리 안에서만 씁니다. if는 반복이 아니라서 if 하나만 빠져나오는 데는 쓸 수 없습니다. 문법 오류라 1번 줄도 실행되지 않았습니다.

자주 틀리는 곳

틀린 생각: continue는 반복을 끝낸다.

break처럼 덩어리 가운데서 흐름을 바꾸는 말이라, 하는 일도 같아 보입니다. continue는 이번 바퀴만 건너뜁니다.

2절 코드의 continue를 break로 바꾸면 결과가 달라집니다.

for ch in '커라커':
    if ch == '라':
        break
    print(ch)
실행 결과
커

break는 '라'에서 반복을 끝내 '커' 하나만 찍습니다. 2절의 continue는 '라'의 바퀴만 건너뛰어 '커'를 둘 찍었습니다.

맞는 규칙: continue는 이번 바퀴의 남은 줄을 건너뛰고 반복 머리로 돌아갑니다. 둘 가운데 반복을 끝내는 것은 break입니다(규칙 4).

틀린 생각: while에서도 continue를 만나면 for처럼 다음 값으로 넘어간다.

for는 continue 뒤에 다음 값을 저절로 꺼내므로, while도 그럴 것 같습니다. while에는 값을 꺼내는 일이 없고, 조건의 이름은 덩어리 안의 줄이 바꿉니다.

아래 코드는 1부터 4까지 가운데 2만 건너뛰고 찍습니다. 값을 바꾸는 3번 줄이 continue보다 앞에 있습니다.

n = 0
while n < 4:
    n = n + 1
    if n == 2:
        continue
    print(n)
실행 결과
1
3
4

값을 바꾸는 줄을 continue 뒤로 옮기면 끝나지 않습니다. 끝나지 않는 코드라서 실행 결과 대신 추적 표로 봅니다.

n = 0
while n < 4:
    if n == 2:
        continue
    n = n + 1
    print(n)
줄바뀐 이름값출력
…
62
2조건 n < 4True
3조건 n == 2True
4continue
2조건 n < 4True
3조건 n == 2True
…

1과 2를 찍고 나면 n은 2입니다. 그 뒤로는 바퀴마다 3번 줄의 조건이 True라 continue가 5~6번 줄을 건너뜁니다. n이 더는 바뀌지 않아 2번 줄의 조건도 늘 True입니다. 이미 돌고 있다면 Ctrl+C로 멈춥니다.

맞는 규칙: continue는 남은 줄을 건너뛰고 조건으로 돌아갈 뿐, 이름을 바꿔 주지 않습니다. while에서는 조건의 이름을 바꾸는 줄을 continue보다 앞에 둡니다(규칙 4).

틀린 생각: 깃발은 바퀴마다 지금 글자가 맞는지에 따라 올리고 내린다.

if에 else를 짝지어 '맞으면 올리고, 아니면 내린다'로 쓰면 빠짐없어 보입니다. 그러나 찾기의 깃발은 지금 글자가 아니라 '한 번이라도 찾았는가'를 나타냅니다.

found = False
for ch in '커라커':
    if ch == '라':
        found = True
    else:
        found = False
print(found)
실행 결과
False

'라'에서 올린 깃발을 다음 글자 '커'에서 else가 다시 내렸습니다. 찾은 자리에서 break로 멈추면 이런 일도 생기지 않습니다.

맞는 규칙: 이름은 마지막에 붙인 값 하나만 가리켜서, 반복 안에서 깃발을 내리면 앞에서 찾은 표시가 지워집니다. 깃발은 반복 앞에서 한 번만 내리고, 찾으면 올린 채 둡니다(규칙 3).

확인 문제

1. 2절의 첫 코드에서 건너뛸 글자를 '라'에서 '커'로 바꿨습니다. 무엇이 찍히는지 그대로 쓰세요.

for ch in '커라커':
    if ch == '커':
        continue
    print(ch)
힌트

글자마다 continue를 만나는지, 만나면 그다음 어느 줄로 가는지 봅니다.

정답
실행 결과
라

첫째와 셋째 바퀴의 '커'는 continue로 4번 줄을 건너뛰고, 둘째 바퀴의 '라'만 찍힙니다.

흔한 오답은 아무것도 찍히지 않는다는 것입니다. 첫 글자 '커'에서 continue가 반복을 끝낸다고 본 것입니다. continue는 이번 바퀴만 건너뜁니다.

2. 주문 기록에 쿠키('쿠')가 있으면 True, 없으면 False를 찍는 코드의 줄이 섞였습니다. 줄 앞의 들여쓰기는 그대로입니다. 1번 줄부터 차례로 기호를 늘어놓으세요.

㉠         break
㉡ print(found)
㉢ for ch in '커라커쿠':
㉣         found = True
㉤ found = False
㉥     if ch == '쿠':
힌트

하위 목표 차례대로 놓습니다 — 깃발 내리기 → 하나씩 보며 찾으면 올리고 멈추기 → 깃발 보고 쓰기.

놓은 뒤 물음

다 맞춘 코드에서 ㉣과 ㉠을 그 차례로 놓는 까닭은 무엇일까요?

  • ① break를 만나면 반복이 바로 끝나서, 뒤에 둔 줄은 실행되지 않기 때문
  • ② break는 if 덩어리만 끝내고, 그다음 found = True로 넘어가기 때문
  • ③ 파이썬은 대입문을 먼저 실행하고 break를 나중에 실행하기 때문
정답

㉤ ㉢ ㉥ ㉣ ㉠ ㉡ 차례이고, 까닭은 ①입니다. 바꿔도 되는 줄은 없습니다.

found = False
for ch in '커라커쿠':
    if ch == '쿠':
        found = True
        break
print(found)
실행 결과
True

㉤을 맨 끝에 둔 ㉢ ㉥ ㉣ ㉠ ㉡ ㉤도 이 기록에서는 True를 찍습니다. 그러나 쿠키가 없는 기록에서는 found가 어떤 값에도 붙기 전에 ㉡이 실행되어 NameError로 멈춥니다. 깃발 내리기는 반복 앞에 둡니다.

㉣과 ㉠은 서로 바꿀 수 없습니다. break가 먼저면 깃발을 올리기 전에 반복이 끝나 False가 찍힙니다.

  • ② break가 if만 빠져나온다고 봤습니다. break는 감싸고 있는 반복(for)을 끝냅니다.
  • ③ 줄의 종류에 따라 실행 차례가 바뀐다고 봤습니다. 파이썬은 위에서 아래로 한 줄씩 실행합니다(규칙 1).

3. 하루 3000걸음씩 걸어 모은 걸음 수가 10000 이상이 되는 날 멈춥니다. 무엇이 찍히는지 고르세요.

total = 0
for day in range(1, 8):
    total = total + 3000
    if total >= 10000:
        break
print(day, total)
  • ① 4 12000
  • ② 7 21000
  • ③ 3 9000
힌트

바퀴마다 day와 total을 추적 표에 적고, break를 만나는 바퀴를 찾습니다.

정답
실행 결과
4 12000

①입니다. total은 3000 → 6000 → 9000 → 12000입니다. 넷째 바퀴에서 12000 >= 10000이 True라 break로 반복이 끝나고, 그때 day는 4입니다.

  • ② break가 반복을 끝내지 않는다고 보고 일곱 바퀴를 다 돌렸습니다. break를 만나면 남은 바퀴는 돌지 않습니다.
  • ③ 10000에 닿기 전날 멈춘다고 봤습니다. 4번 줄의 조건은 3번 줄에서 더한 뒤에 보므로, 10000 이상이 된 날(넷째 날)에 멈춥니다.

아래 확인 문제 3 코드의 5번 줄 break를 continue로 바꾸면 찍히는 줄을 봅니다.

처음 펼 때 약 6MB를 받습니다.컴퓨터에서 해 보기

끝까지 내려오면 저절로 표시됩니다. 이 기기에만 저장합니다.

파이썬 목차로