PYTHON

파이썬 while 반복문 — 멈추지 않는 프로그램, 범인은 빠진 한 줄

PANCO_IT
#파이썬#python#while#반복문#무한루프#break#continue#파이썬기초#파이썬독학

밤에 불이 켜진 회전목마가 돌아가는 모습을 가까이서 찍은 사진

이미지 출처: Pexels · Pexels License

카운트다운을 만들어 보려던 날이었습니다. 0부터 4까지 다섯 줄만 찍고 끝나면 되는 프로그램. 여섯 줄을 쓰고 실행 버튼을 눌렀습니다. 화면에 0이 찍혔고, 그 아래 또 0, 또 0. 스크롤이 내려가는 속도가 읽는 속도보다 빨랐습니다.

# 실행하지 마세요. 멈추지 않습니다.
count = 0
while count < 5:
    print(count)
print("끝")
0
0
0
0
(같은 줄이 계속)

8편에서 배운 for는 리스트 칸이 끝나면 저절로 멈췄습니다. 이 프로그램은 스스로 멈추지 않습니다. 브라우저 실행창이면 몇 초 뒤 시간 초과로 끊기고, 내 컴퓨터 터미널이면 Ctrl과 C를 함께 눌러 강제로 끊어야 합니다. 여섯 줄 중 어디가 문제인지, 오늘은 그 범인을 찾습니다.

while이 뭔가요 — 조건이 참인 동안

정의부터 세웁니다. 파이썬 공식 자습서(2026년 9월 9일 기준 3.13판)는 while을 이렇게 정의합니다. 조건이 참인 동안 블록을 되풀이한다. for가 "이 묶음을 하나씩 다 돌 때까지"라면, while은 "이 조건이 참인 한 계속"입니다. 몇 번 돌지는 미리 정해져 있지 않고, 조건이 거짓이 되는 순간이 곧 끝입니다.

한 바퀴의 순서는 언제나 같습니다. 조건을 검사한다, 참이면 들여쓴 블록을 한 번 실행한다, 다시 조건으로 돌아간다. 거짓이면 블록을 건너뛰고 while 아래 줄로 내려갑니다. 그래서 while 문장에는 눈에 보이지 않는 세 부품이 있습니다. 조건에 쓰이는 값의 처음 값, 매 바퀴 검사하는 조건, 그리고 블록 안에서 그 값을 바꾸는 갱신. 셋 중 하나가 빠지면 반복은 시작하지 못하거나 끝나지 못합니다.

while 한 바퀴의 흐름. count = 0으로 시작해 count < 5 검사, 참이면 print(count) 실행 뒤 count += 1로 갱신하고 다시 검사로 돌아가며, 값이 0 1 2 3 4를 거쳐 5가 되면 거짓이라 끝으로 빠진다. 갱신 줄이 빠진 경로는 점선으로 표시

한 바퀴는 검사, 실행, 갱신 순서입니다. count가 0에서 5로 자라며 다섯 번 돌고, 5가 되는 순간 조건이 거짓이라 끝으로 나옵니다. 점선 자리가 오늘 사건의 현장입니다.

성질은 넷입니다.

성질위 코드에서
조건으로 돈다횟수가 아니라 참·거짓이 반복을 결정한다count < 5가 참인 동안
검사가 먼저다블록보다 조건을 먼저 본다. 처음부터 거짓이면 한 번도 안 돈다count = 5로 시작하면 출력이 없다
끝은 내가 만든다조건을 거짓으로 만드는 줄이 블록 안에 있어야 한다count += 1
중간에 끊을 수 있다break로 즉시 탈출, continue로 이번 바퀴만 건너뛴다아래 비밀번호 예제

앞으로 이 뜻으로 쓰는 낱말입니다.

용어
조건식while 뒤에 오는 참·거짓 식. count < 5
갱신조건에 쓰인 값을 블록 안에서 바꾸는 줄. count += 1
무한 루프조건이 영원히 참이라 끝나지 않는 반복
break반복을 그 자리에서 끝내고 블록 밖으로 나간다
continue이번 바퀴의 남은 줄을 건너뛰고 조건 검사로 돌아간다
while ... else반복이 break 없이 끝났을 때만 실행되는 블록

증상 — 0이 멈추지 않습니다

첫 단서는 찍힌 값입니다. 0만 나옵니다. 1이나 2가 한 번도 안 보입니다. 반복은 돌고 있는데 count가 자라지 않는다는 뜻입니다.

어두운 터미널 화면에 0이 여러 줄 반복해 찍혀 있고 아래로 갈수록 흐려지며, 오른쪽에 멈추지 않음과 Ctrl + C로 강제 종료라는 표시가 붙어 있다

터미널에 0만 쌓입니다. 1이 한 번도 안 나온다는 사실이 범인을 가리키는 첫 단서입니다.

용의자 하나 — 조건이 틀렸나

count < 5를 봅니다. 0은 5보다 작으니 참, 그래서 블록이 실행됩니다. 여기까지는 맞습니다. 만약 count > 5라고 썼다면 처음부터 거짓이라 한 줄도 안 찍혔을 것이고, count <= 5라면 0부터 5까지 여섯 줄이 나왔을 것입니다. 지금 증상은 둘 다 아닙니다. 조건은 무죄입니다.

조건식만 따로 확인하기 — 참인지 거짓인지
count = 0
print(count < 5)
print(count > 5)
count = 5
print(count < 5)

📱 코드 실행(실습)은 태블릿·PC에서 이용할 수 있어요. 모바일에서는 위 코드를 눈으로 따라가며 확인하세요.

True
False
False

용의자 둘 — 들여쓰기가 잘못됐나

6편에서 들여쓰기가 문법이었습니다. print(count)는 네 칸 안쪽에 있으니 블록 안이고, print("끝")은 왼쪽 끝에 붙어 있으니 반복이 끝난 뒤 한 번 실행되는 줄입니다. 블록 범위도 맞습니다. 들여쓰기도 무죄.

진범 — 조건에 쓰인 값이 한 번도 바뀌지 않았습니다

남은 것은 하나입니다. count는 0으로 시작했고, 블록 안에서 count를 건드리는 줄이 없습니다. 검사할 때마다 count는 여전히 0이고, 0은 언제나 5보다 작습니다. 조건이 거짓이 될 길이 없으니 끝도 없습니다. 이것이 무한 루프이고, 원인은 빠진 갱신 한 줄입니다.

갱신 한 줄을 넣은 코드 — 다섯 번 돌고 멈춥니다
count = 0
while count < 5:
  print(count)
  count += 1
print("끝, count =", count)

📱 코드 실행(실습)은 태블릿·PC에서 이용할 수 있어요. 모바일에서는 위 코드를 눈으로 따라가며 확인하세요.

0
1
2
3
4
끝, count = 5

count += 1count = count + 1을 줄여 쓴 것입니다. 한 바퀴마다 1씩 커져 0, 1, 2, 3, 4를 찍고, 5가 되면 count < 5가 거짓이라 반복이 끝납니다. 마지막 줄이 count = 5인 점도 눈여겨볼 대목입니다. 반복이 끝난 뒤에도 그 값은 남아 있습니다.

for가 이 사건을 겪지 않는 이유도 여기서 보입니다. for는 다음 값을 꺼내는 일과 끝을 판단하는 일을 파이썬이 대신합니다. while은 둘 다 내 몫입니다. 자유로운 대신 책임도 따라옵니다.

재발 방지 — 세 줄 점검과 안전장치

while을 쓸 때마다 세 줄을 눈으로 확인하는 습관이 가장 싸게 먹힙니다. 처음 값이 있는가, 조건이 언젠가 거짓이 되는가, 블록 안에서 그 값이 바뀌는가. 특히 셋째 줄은 블록 맨 아래에 두는 편이 눈에 잘 띕니다.

값이 바뀌기는 하는데 조건을 영영 못 만나는 경우도 있습니다. 1에서 시작해 2배씩 키우며 100이 되기를 기다리면, 64 다음이 128이라 100을 그냥 지나칩니다. 이럴 때는 횟수 상한을 하나 더 두면 프로그램이 스스로 멈춥니다.

안전장치 — 20번 넘게 돌면 강제로 끝냅니다
x = 1
steps = 0
while x != 100:
  x *= 2
  steps += 1
  if steps > 20:
      print("20번 넘게 돌아도 못 끝냈습니다. x =", x)
      break

📱 코드 실행(실습)은 태블릿·PC에서 이용할 수 있어요. 모바일에서는 위 코드를 눈으로 따라가며 확인하세요.

20번 넘게 돌아도 못 끝냈습니다. x = 2097152

x != 100은 "100이 아닌 동안"이라는 뜻인데 x가 100이 되는 일은 없습니다. steps가 21이 되는 순간 break가 반복을 끊어 줍니다. 저는 조건이 조금이라도 미덥지 않으면 이 상한을 습관처럼 넣습니다. 나중에 지워도 되고, 남겨 두어도 해가 없습니다.

일부러 멈추지 않게 만들고 break로 나갑니다

무한 루프가 항상 사고는 아닙니다. 메뉴를 보여 주고 사용자가 종료를 누를 때까지 기다리는 프로그램은 애초에 끝을 조건으로 쓰기 어렵습니다. 그럴 때 조건을 True로 고정해 "일단 계속 돈다"로 시작하고, 나갈 지점에서 break를 씁니다.

while True와 break — 0을 누를 때까지 도는 메뉴
inputs = ["1", "1", "9", "0"]   # 사용자가 누른 순서를 미리 적어 둔 것입니다
i = 0
total = 0
while True:
  cmd = inputs[i]
  i += 1
  if cmd == "0":
      print("종료, 누른 횟수", total)
      break
  if cmd not in ("1", "2"):
      print("없는 메뉴:", cmd)
      continue
  total += 1
  print("메뉴", cmd, "실행")

📱 코드 실행(실습)은 태블릿·PC에서 이용할 수 있어요. 모바일에서는 위 코드를 눈으로 따라가며 확인하세요.

메뉴 1 실행
메뉴 1 실행
없는 메뉴: 9
종료, 누른 횟수 2

inputs는 4편의 input()을 흉내 낸 것입니다. 실행창에서 매번 입력을 받기 어려워 누른 순서를 리스트에 적어 두었습니다. "0"을 만나면 break가 반복을 끝내고, "9"처럼 없는 메뉴는 continue가 아래 두 줄을 건너뛰어 다음 입력으로 넘어갑니다. breakcontinue가 한 블록에 같이 있는 모습이 실제 프로그램의 흔한 생김새입니다.

달리기 트랙 그림. 출발선에서 시작해 트랙을 도는 주자가 있고, break는 트랙 옆으로 빠져나가는 화살표, continue는 남은 구간을 건너뛰어 출발선으로 돌아가는 점선 화살표로 표시

트랙 한 바퀴가 블록 한 번입니다. break는 트랙을 아예 벗어나고, continue는 남은 구간을 건너뛰어 출발선으로 돌아가 다음 바퀴 검사를 받습니다.

비밀번호를 세 번까지만 받는 프로그램도 같은 구조입니다. 여기에는 while의 짝인 else가 하나 더 붙습니다.

세 번 안에 맞히면 break, 다 틀리면 else
answer = "1234"
attempts = ["1111", "2222", "1234"]
tries = 0
while tries < 3:
  guess = attempts[tries]
  tries += 1
  if guess == answer:
      print(tries, "번째에 맞았습니다")
      break
  print(tries, "번째 실패:", guess)
else:
  print("3번 모두 실패, 잠깁니다")

📱 코드 실행(실습)은 태블릿·PC에서 이용할 수 있어요. 모바일에서는 위 코드를 눈으로 따라가며 확인하세요.

1 번째 실패: 1111
2 번째 실패: 2222
3 번째에 맞았습니다

else는 반복이 break 없이 조건으로 끝났을 때만 실행됩니다. 위 실행은 세 번째에 맞아 break로 나왔으니 else가 돌지 않았습니다. attempts의 마지막 값을 "9999"로 바꾸면 세 번 다 실패하고 잠깁니다 문장이 나옵니다. ifelse와 이름은 같지만 뜻이 달라 처음엔 낯선데, "끝까지 다 돌았을 때"로 읽으면 됩니다.

continue — 이번 바퀴만 건너뛰기

continue만 따로 봅니다. 1부터 10까지 가는 동안 짝수는 찍지 않는 코드입니다.

짝수는 건너뛰고 홀수만 — 갱신 줄의 위치를 보세요
n = 0
while n < 10:
  n += 1
  if n % 2 == 0:
      continue
  print(n, end=" ")
print()

📱 코드 실행(실습)은 태블릿·PC에서 이용할 수 있어요. 모바일에서는 위 코드를 눈으로 따라가며 확인하세요.

1 3 5 7 9 

갱신 n += 1이 블록 맨 위에 있습니다. continue는 아래 줄을 건너뛰기 때문에, 갱신을 continue 뒤에 두면 짝수에서 n이 안 자라고 그 자리에 머무는 무한 루프가 됩니다. continue가 있는 블록에서 갱신 줄은 continue보다 위에 둔다. 이 한 줄이 오늘 사건의 두 번째 재발 방지 수칙입니다.

for와 while, 어느 쪽을 쓰나

같은 일을 둘 다로 쓸 수 있습니다. 세 번 인사하는 코드입니다.

같은 일, 두 문법
for k in range(3):
  print("for", k)
k = 0
while k < 3:
  print("while", k)
  k += 1

📱 코드 실행(실습)은 태블릿·PC에서 이용할 수 있어요. 모바일에서는 위 코드를 눈으로 따라가며 확인하세요.

for 0
for 1
for 2
while 0
while 1
while 2

돌 횟수를 미리 알거나 돌 묶음이 있으면 for가 짧고 안전합니다. 처음 값과 갱신을 파이썬이 맡아 주니 빠뜨릴 줄이 없습니다. 반대로 몇 번인지 모르고 조건이 끝을 정하는 일은 while의 자리입니다. 잔액이 남아 있는 동안 커피를 사는 코드는 몇 잔이 될지 미리 알 수 없습니다.

잔액이 커피 값 이상인 동안 — 몇 잔인지는 돌아 보면 압니다
balance = 10000
price = 3000
cups = 0
while balance >= price:
  balance -= price
  cups += 1
print(cups, "잔,", balance, "원 남음")

📱 코드 실행(실습)은 태블릿·PC에서 이용할 수 있어요. 모바일에서는 위 코드를 눈으로 따라가며 확인하세요.

3 잔, 1000 원 남음

for와 while 선택 흐름. 몇 번 돌지 아는가 또는 돌 묶음이 있는가에 예이면 for와 range·리스트, 아니오이면 무엇이 끝내는가로 이어지고, 조건이면 while 조건식, 사용자나 외부 신호이면 while True와 break로 갈린다

횟수나 묶음이 있으면 for, 조건이 끝을 정하면 while, 끝을 사용자가 정하면 while True와 break입니다. 세 갈래만 기억하면 대부분 정해집니다.

while 하나로 본 문법 여덟 개

문법이 글의 예
while 조건:조건이 참인 동안 블록 반복while count < 5:
처음 값조건에 쓰이는 값을 반복 전에 정한다count = 0
갱신블록 안에서 조건 값을 바꾼다count += 1
while True:조건을 고정해 일단 계속 돈다메뉴 예제
break반복 즉시 종료if cmd == "0": break
continue이번 바퀴 남은 줄 건너뛰기짝수 건너뛰기
while ... else:break 없이 끝났을 때 한 번 실행비밀번호 3회
횟수 상한조건이 미덥지 않을 때의 안전장치if steps > 20: break

한 줄만 바꾸면 출력은 어떻게 될까요

미니 퀴즈

OX 3문제 + 4지선다 4문제

참고 자료


포켓코딩(PYTHON1) 9편 · 8편(파이썬 for 반복문)에서 이어집니다. 예제 코드는 강사 개인 GitHub 저장소의 강의 자료를 바탕으로 다시 썼습니다. 다음 편은 함수입니다. 같은 코드를 이름 하나로 다시 쓰는 def와, return이 없으면 왜 None이 나오는지를 다룹니다.

PANCO_IT

IT 지식을 정리하는 개발자

관련 글

PYTHON

파이썬 for 반복문 — 장바구니 영수증으로 익히는 range와 빠지는 끝 번호

장바구니 다섯 개의 값을 더하는 영수증을 for 반복문으로 만듭니다. 1부터 10까지 더했는데 45가 나온 첫 시도에서 range의 끝 번호가 빠진다는 규칙을 찾고, 리스트를 직접 돌고, 돌면서 지우면 한 칸을 건너뛰는 이유까지 확인합니다.

· 파이썬, python, for문
PYTHON

파이썬 리스트 — 장바구니 열아홉 줄로 익히는 인덱스·슬라이싱·append·pop

장 볼 물건 다섯 개를 변수 다섯 개에 담을 수는 없습니다. 리스트가 무엇인지 공식 문서의 정의로 먼저 세우고, 주석 없는 열아홉 줄을 위에서 아래로 읽으며 0부터 세는 번호, 끝이 빠지는 슬라이싱, append와 pop, 복사가 아니었던 = 한 줄을 확인합니다.

· 파이썬, python, 리스트
PYTHON

파이썬 if 조건문 — 아홉 줄짜리 합격 판정기에 숨은 실수 세 개(=, 들여쓰기, elif 순서)

점수를 받아 만점·우수 합격·합격·불합격을 가르는 아홉 줄 코드에 실수가 세 개 들어 있습니다. 하나는 첫 줄부터 멈추고, 하나는 들여쓰기에서 멈추고, 마지막 하나는 에러 없이 조용히 틀린 답을 냅니다. 셋을 차례로 잡아내면서 if·elif·else와 비교 연산자, 들여쓰기 규칙을 익힙니다.

· 파이썬, python, if문