while 문은 조건이 참인 동안 들여 쓴 덩어리를 되풀이합니다. 조건은 덩어리를 시작할 때마다 다시 봅니다.
if 문은 덩어리를 한 번 실행할지 고를 뿐입니다. 손님 번호를 1부터 3까지 부르려면 print를 세 줄 써야 하고, 100까지 부르려면 100줄을 써야 합니다. while 문은 덩어리 하나를 조건이 참인 동안 되풀이해서 같은 일을 몇 줄로 끝냅니다. 같은 줄이 여러 번 실행되면 머릿속으로 따라가기가 어려워집니다. 그래서 이 레슨에서는 실행된 줄을 차례로 적어 가는 추적 표(trace table)도 함께 배웁니다.
이 단원(반복)을 이미 안다면 단원 연습 문제부터 풀고 틀린 레슨만 보세요.
1조건이 참인 동안 되풀이하는 while
while 문의 꼴은 if 문과 같습니다. while 다음에 조건을 쓰고 콜론(:)으로 끝낸 뒤, 되풀이할 줄을 4칸 들여 씁니다. 들여 쓴 줄이 덩어리입니다.
n = 0
while n < 3:
n = n + 1
print(n)
print('끝')
1
2
3
끝파이썬은 이 코드를 이렇게 실행합니다.
- 1번 줄:
n을 0에 붙입니다. - 2번 줄: 조건
n < 3을 봅니다.0 < 3은True라서 덩어리로 들어갑니다. - 3~4번 줄: 덩어리를 위에서 아래로 한 번 실행합니다.
n이 1에 다시 붙고, 1이 찍힙니다. - 덩어리 끝에 닿으면 2번 줄로 돌아가 조건을 다시 봅니다.
- 조건이
False면 덩어리를 건너뛰고, 들여 쓰지 않은 다음 줄인 5번 줄로 갑니다.
덩어리를 한 번 실행하는 것을 한 바퀴라고 부릅니다. 이 코드는 세 바퀴를 돈 뒤 끝을 찍습니다.
if와 else에서 세운 규칙 4에 반복 쪽을 더하면 이렇습니다.
규칙 4. 들여쓰기가 덩어리를 정합니다.
if는 덩어리를 한 번 실행할지 고르고,for·while은 덩어리를 되풀이합니다.while조건은 덩어리를 시작할 때마다 봅니다.
2조건은 덩어리를 시작할 때만 본다
1절 코드의 셋째 바퀴를 다시 봅니다. 3번 줄에서 n이 3에 붙는 순간 조건 n < 3은 거짓이 됩니다. 그래도 4번 줄은 실행되어 3이 찍힙니다.
while 문은 조건을 늘 지켜보지 않습니다. 2번 줄에 올 때, 곧 덩어리를 시작할 때만 봅니다.
이번에는 n이 첫 바퀴에서 단번에 3을 넘습니다. 아래 코드는 무엇을 찍을까요? 답을 정한 뒤 펼쳐 보세요.
n = 0
while n < 3:
n = n + 5
print(n)
실행 결과 보기
5예상과 다르면 그곳이 배울 곳입니다.
3번 줄에서 n이 5에 붙어 조건이 거짓이 되어도, 이 바퀴는 4번 줄까지 마저 실행해 5를 찍습니다.
다시 2번 줄에 와서야 5 < 3이 False라서 반복이 끝납니다.
3추적 표로 한 줄씩 따라가기
추적 표는 실행되는 줄을 차례로 적는 표입니다. 칸은 넷입니다 — 줄, 바뀐 이름, 값, 출력. 쓰는 규칙도 넷입니다.
- 줄이 하나 실행될 때마다 표에 한 줄을 씁니다. 같은 줄이 다시 실행되면 다시 씁니다.
- 대입하는 줄은 바뀐 이름과 새 값을 씁니다.
while줄은 이름을 바꾸지 않습니다. 바뀐 이름 칸에 조건을, 값 칸에True·False를 씁니다.print줄은 찍힌 글자를 출력 칸에 씁니다.
1절 코드를 추적 표로 따라가면 이렇습니다.
| 줄 | 바뀐 이름 | 값 | 출력 |
|---|---|---|---|
| 1 | n | 0 | |
| 2 | 조건 n < 3 | True | |
| 3 | n | 1 | |
| 4 | 1 | ||
| 2 | 조건 n < 3 | True | |
| 3 | n | 2 | |
| 4 | 2 | ||
| 2 | 조건 n < 3 | True | |
| 3 | n | 3 | |
| 4 | 3 | ||
| 2 | 조건 n < 3 | False | |
| 5 | 끝 |
출력 칸을 위에서 아래로 읽으면 1, 2, 3, 끝입니다. 실행 결과와 같습니다.
조건이 True인 줄이 셋이니 세 바퀴입니다. 반복 횟수는 이렇게 셉니다.
표는 끝까지 씁니다. 반만 쓰고 나머지를 머릿속으로 셈하면 조건을 보는 줄처럼 틀리기 쉬운 데서 틀립니다.
4끝나지 않는 반복
덩어리 안에 조건에 쓰인 이름을 바꾸는 줄이 없으면 조건은 늘 같은 값입니다.
1절 코드에서 3번 줄 n = n + 1을 빠뜨리면 아래 코드가 됩니다. 끝나지 않는 코드라서 실행 결과 대신 추적 표로 봅니다.
n = 0
while n < 3:
print(n)
print('끝')
| 줄 | 바뀐 이름 | 값 | 출력 |
|---|---|---|---|
| 1 | n | 0 | |
| 2 | 조건 n < 3 | True | |
| 3 | 0 | ||
| 2 | 조건 n < 3 | True | |
| 3 | 0 | ||
| … |
n이 늘 0이라서 2번 줄의 조건은 늘 True이고, 0이 끝없이 찍힙니다.
이런 반복은 IDLE이나 터미널에서 Ctrl+C를 눌러 멈춥니다. 맨 아래 줄에 KeyboardInterrupt(키보드로 끊음)가 찍힙니다.
예제
쿠키를 몇 개 살 수 있을까
7000원으로 2000원짜리 쿠키를 몇 개 사고 얼마가 남는지 셉니다. 남은 돈이 2000원 이상인 동안 하나씩 삽니다.
몇 바퀴를 돌지는 처음 가진 돈에 따라 달라집니다. 이렇게 몇 번 되풀이할지 미리 정해지지 않은 일에 while을 씁니다.
money = 7000
count = 0
while money >= 2000:
money = money - 2000
count = count + 1
print(count, money)
3 1000세 바퀴를 돌고 나면 money가 1000이라 3번 줄의 조건 1000 >= 2000이 False입니다. 쿠키는 3개, 남은 돈은 1000원입니다.
덩어리를 들여 쓰지 않으면
while 줄 다음에 들여 쓴 줄이 하나도 없으면 오류가 납니다.
n = 0
while n < 3:
n = n + 1
File "main.py", line 3 n = n + 1 ^IndentationError: expected an indented block after 'while' statement on line 2맨 아래 줄은 if와 else에서 본 들여쓰기 오류(IndentationError)이고, if 자리가 while로 바뀌었을 뿐입니다.
3번 줄을 4칸 들여 쓰면 덩어리가 됩니다. 문법 오류라서 1번 줄도 실행되지 않았습니다.
자주 틀리는 곳
틀린 생각: 조건이 거짓이 되는 순간 반복이 멈춘다.
while은 '~하는 동안'이라는 뜻이라, 조건을 쉬지 않고 지켜본다고 여기기 쉽습니다.
2절 코드는 3번 줄 n = n + 5에서 조건이 거짓이 되어도 4번 줄을 실행해 5를 찍었고, 반복은 그다음 2번 줄에서 끝났습니다.
맞는 규칙: while 조건은 덩어리를 시작할 때만 봅니다. 그래서 덩어리 가운데서 조건이 거짓이 되어도 그 바퀴는 끝까지 실행합니다(규칙 4).
틀린 생각: while 자리에 if를 써도 덩어리가 되풀이된다.
1절에서 본 대로 두 문은 꼴이 같지만, if는 조건으로 되돌아가지 않습니다.
1절 코드에서 while만 if로 바꿨습니다.
n = 0
if n < 3:
n = n + 1
print(n)
print('끝')
1
끝덩어리를 한 번 실행해 1을 찍은 뒤, 2번 줄로 돌아가지 않고 5번 줄로 내려가 끝을 찍습니다.
맞는 규칙: if는 조건을 한 번 보고 덩어리를 많아야 한 번 실행합니다. 되풀이는 while이 합니다(규칙 4).
틀린 생각: 조건에 쓰인 이름을 덩어리 안에서 바꾸지 않아도 반복은 언젠가 끝난다.
사람에게 'n이 3보다 작은 동안 n을 불러라'라고 하면 알아서 하나씩 늘려 가며 부릅니다. 파이썬은 쓴 줄만 실행하고, 이름을 알아서 바꾸지 않습니다.
4절 코드는 n을 바꾸는 줄이 없어서 2번 줄의 조건이 바퀴마다 0 < 3이고, 0을 끝없이 찍습니다.
맞는 규칙: 조건이 참인 채 조건에 쓰인 이름이 그대로면 조건은 바퀴마다 같은 값이라 반복이 끝나지 않습니다. 반복을 쓰면 덩어리 안에 그 이름을 바꾸는 줄이 있는지 먼저 봅니다(규칙 4).
틀린 생각: 추적 표는 값이 바뀌는 줄만 써도 된다.
조건을 보는 줄은 이름을 바꾸지 않으니 적지 않아도 될 것 같습니다. 그러나 반복이 몇 바퀴 돌고 언제 끝나는지는 그 줄에서 정해집니다.
3절 표에서 조건 줄을 빼면, n이 3이 된 뒤 한 바퀴를 더 도는지 표만 보고는 알 수 없습니다. False가 적힌 마지막 조건 줄이 있어야 반복이 왜 끝났는지 보입니다.
맞는 규칙: 추적 표에는 조건을 보는 줄까지, 실행되는 줄을 하나도 빼지 않고 끝까지 씁니다.
확인 문제
1. 예제의 첫 줄을 money = 6000으로 바꿨습니다. 무엇이 찍히는지 그대로 쓰세요.
money = 6000
count = 0
while money >= 2000:
money = money - 2000
count = count + 1
print(count, money)
힌트
3번 줄의 조건을 바퀴마다 봅니다. money가 2000인 바퀴에서 >= 연산자를 따져 봅니다.
정답
3 0money는 6000 → 4000 → 2000 → 0으로 바뀝니다. 셋째 바퀴를 시작할 때 2000 >= 2000은 True라서 한 번 더 삽니다. 넷째 바퀴를 시작할 때 0 >= 2000이 False라 반복이 끝납니다.
흔한 오답은 2 2000입니다. >= 연산자를 '보다 크다'로 읽어 2000일 때 멈춘다고 본 것입니다.
2. 예제(쿠키)를 추적 표로 따라갑니다. 표의 (가)~(라)를 채우세요.
money = 7000
count = 0
while money >= 2000:
money = money - 2000
count = count + 1
print(count, money)
표의 줄 칸은 실행된 줄의 번호입니다.
| 줄 | 바뀐 이름 | 값 | 출력 |
|---|---|---|---|
| 1 | money | 7000 | |
| 2 | count | 0 | |
| 3 | 조건 money >= 2000 | True | |
| 4 | money | 5000 | |
| 5 | count | 1 | |
| 3 | 조건 money >= 2000 | (가) | |
| 4 | money | 3000 | |
| 5 | count | 2 | |
| 3 | 조건 money >= 2000 | True | |
| (나) | money | 1000 | |
| 5 | count | 3 | |
| 3 | 조건 money >= 2000 | (다) | |
| 6 | (라) |
힌트
표의 앞 바퀴들에서 줄 칸이 어떤 차례로 되풀이되는지 봅니다.
정답
(가) True · (나) 4 · (다) False · (라) 3 1000
(가)는 5000 >= 2000이라 True입니다. (나)는 셋째 바퀴의 4번 줄입니다. (다)는 1000 >= 2000이라 False이고, 반복을 빠져나가 6번 줄이 3 1000을 찍습니다.
손으로 표를 쓸 때 흔히 빠뜨리는 줄이 (다)입니다. 마지막에 조건을 본 줄도 실행된 줄이라 한 줄을 씁니다. 이 줄이 있어야 반복이 왜 끝났는지 표에 보입니다.
3. 하루에 4000걸음씩 걸어 10000걸음을 채우려 합니다. 이 코드가 줄마다 찍는 값을 고르세요.
steps = 0
while steps < 10000:
steps = steps + 4000
print(steps)
- ①
4000 - ②
4000,8000 - ③
4000,8000,12000
힌트
추적 표에 바퀴마다 2번 줄의 조건과 steps 값을 적어 봅니다.
정답
4000
8000
12000③입니다. 셋째 바퀴를 시작할 때 8000 < 10000은 True라서 덩어리로 들어갑니다. 3번 줄에서 12000이 되어 조건이 거짓이 되어도 4번 줄까지 마저 실행해 12000을 찍습니다.
- ① 덩어리를 한 번만 실행한다고 봤습니다. 한 번 고르는 것은
if이고,while은 조건이 참인 동안 되풀이합니다. - ② 12000이 되어 조건이 거짓이 되는 순간 반복이 멈춘다고 봤습니다(조건을 늘 지켜본다는 생각). 조건은 바퀴를 시작할 때만 봅니다.
아래 1절 코드의 3번 줄 n = n + 1을 n = n + 2로 바꾸면 찍히는 줄을 모두 봅니다.
처음 펼 때 약 6MB를 받습니다.컴퓨터에서 해 보기
파이썬 3.14. Tab을 누르면 다음 단추나 칸으로 갑니다. 들여쓰기는 빈칸 네 개입니다. Enter는 앞줄 들여쓰기를 잇고, 콜론 뒤에서는 한 단계 더 들여 씁니다. Ctrl+Enter로 실행합니다.
'실행'을 누르면 여기에 나옵니다.
여기서 쓴 코드 · 내 예상은 저장하지도 운영자에게 보내지도 않습니다. 페이지를 새로 열면 처음 코드입니다.