본문으로 건너뛰기

while과 추적 표

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

목차

while 문은 조건이 참인 동안 들여 쓴 덩어리를 되풀이합니다. 조건은 덩어리를 시작할 때마다 다시 봅니다.

if 문은 덩어리를 한 번 실행할지 고를 뿐입니다. 손님 번호를 1부터 3까지 부르려면 print를 세 줄 써야 하고, 100까지 부르려면 100줄을 써야 합니다. while 문은 덩어리 하나를 조건이 참인 동안 되풀이해서 같은 일을 몇 줄로 끝냅니다. 같은 줄이 여러 번 실행되면 머릿속으로 따라가기가 어려워집니다. 그래서 이 레슨에서는 실행된 줄을 차례로 적어 가는 추적 표(trace table)도 함께 배웁니다.

이 단원(반복)을 이미 안다면 단원 연습 문제부터 풀고 틀린 레슨만 보세요.

14단계 중 1단계. 다음을 누르면 1번 줄부터 한 줄씩 실행합니다. 줄이 하나 실행될 때마다 추적 표에 한 줄이 쌓입니다.

1조건이 참인 동안 되풀이하는 while

while 문의 꼴은 if 문과 같습니다. while 다음에 조건을 쓰고 콜론(:)으로 끝낸 뒤, 되풀이할 줄을 4칸 들여 씁니다. 들여 쓴 줄이 덩어리입니다.

n = 0
while n < 3:
    n = n + 1
    print(n)
print('끝')
실행 결과
1
2
3
끝

파이썬은 이 코드를 이렇게 실행합니다.

  1. 1번 줄: n을 0에 붙입니다.
  2. 2번 줄: 조건 n < 3을 봅니다. 0 < 3은 True라서 덩어리로 들어갑니다.
  3. 3~4번 줄: 덩어리를 위에서 아래로 한 번 실행합니다. n이 1에 다시 붙고, 1이 찍힙니다.
  4. 덩어리 끝에 닿으면 2번 줄로 돌아가 조건을 다시 봅니다.
  5. 조건이 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절 코드를 추적 표로 따라가면 이렇습니다.

줄바뀐 이름값출력
1n0
2조건 n < 3True
3n1
41
2조건 n < 3True
3n2
42
2조건 n < 3True
3n3
43
2조건 n < 3False
5끝

출력 칸을 위에서 아래로 읽으면 1, 2, 3, 끝입니다. 실행 결과와 같습니다. 조건이 True인 줄이 셋이니 세 바퀴입니다. 반복 횟수는 이렇게 셉니다.

표는 끝까지 씁니다. 반만 쓰고 나머지를 머릿속으로 셈하면 조건을 보는 줄처럼 틀리기 쉬운 데서 틀립니다.

4끝나지 않는 반복

덩어리 안에 조건에 쓰인 이름을 바꾸는 줄이 없으면 조건은 늘 같은 값입니다. 1절 코드에서 3번 줄 n = n + 1을 빠뜨리면 아래 코드가 됩니다. 끝나지 않는 코드라서 실행 결과 대신 추적 표로 봅니다.

n = 0
while n < 3:
    print(n)
print('끝')
줄바뀐 이름값출력
1n0
2조건 n < 3True
30
2조건 n < 3True
30
…

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 0

money는 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)

표의 줄 칸은 실행된 줄의 번호입니다.

줄바뀐 이름값출력
1money7000
2count0
3조건 money >= 2000True
4money5000
5count1
3조건 money >= 2000(가)
4money3000
5count2
3조건 money >= 2000True
(나)money1000
5count3
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를 받습니다.컴퓨터에서 해 보기

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

파이썬 목차로