
딥러닝 코드에서 가장 자주 보는 두 줄이 뭔지 아시나요? if x > 0: return x 와 for epoch in range(300): 입니다. 🚦
하나는 ReLU, 하나는 에폭 루프예요. 둘 다 "고급 딥러닝"이 아니라 조건문과 반복문입니다. 이번 글에서는 if·elif·else로 갈림길을 고르는 법, for·while·continue·break로 흐름을 다루는 법, 그리고 묶어쓰기(컴프리헨션) 와 풀어쓰기를 자유롭게 오가는 법까지 정리합니다.
📘 이 글은 위키독스 도서 Zero to 머신러닝 딥러닝 Master 의 02-03 🔁 3부 — 흐름 제어: 조건과 반복 을 블로그용으로 다듬은 글입니다.
💻 실습 코드: GitHub · 🏠 mldict.net · ✍️ 기술 블로그
💻 이 글의 코드:
02-03-control-flow· Open in Colab — 핵심 코드와 실제 실행 결과는 글 아래 💻 GitHub 실습 섹션에 있습니다.
⬅️ 이전 글: #35 파이썬 자료형 완전 정복 — 변수는 이름표, list·tuple·dict·set 고르는 법과 형변환·초보자 3대 에러 (02권 2부) \
➡️ 다음 글: #37 파이썬 함수와 메모리 — 스코프·UnboundLocalError·뮤터블 인자부터 GIL·클로저·데코레이터까지 (02권 4부)
if·elif·else는 위에서부터 처음 맞는 하나만 실행합니다. 그래서 조건의 순서가 곧 우선순위이고, =(대입)와 ==(비교)를 혼동하면 SyntaxError가 납니다.for, 모르면 while입니다. continue는 이번 칸만 건너뛰고, break는 반복 자체를 끝냅니다. 무한 루프가 나면 Ctrl+C로 끊으세요.zip이 모두 여기서 나옵니다.🔗 지난 글 복습: #35 파이썬 자료형 완전 정복 (02권 2부)에서 변수는 이름표라는 원리와 list·tuple·dict·set을 골랐습니다. 이번 글은 그 그릇 안의 값을 조건으로 가르고 반복으로 돌리는 흐름 제어입니다.
🔍 더 쉽게 이해하기 — 🚦 갈림길과 신호등
if는 "만약 ~라면"이라는 갈림길입니다.\
🟢 if 조건: — 조건이 맞으면 이 길로\
🟡 elif 조건: — 아니고 이 조건이면 저 길로 (else if의 줄임말)\
🔴 else: — 위에 다 아니면 남은 길로\
📌 콜론(:)과 들여쓰기가 필수입니다. 콜론은 "여기부터 그 길의 내용"이라는 표시입니다.
🔣 비교 · 논리 연산자
| 연산자 | 뜻 | 예시 |
|---|---|---|
== / != | 같다 / 다르다 | score == 100 |
>= / <= | 이상 / 이하 | age >= 18 |
and | 둘 다 참이어야 | a > 0 and b > 0 |
or | 하나만 참이면 | a < 0 or b < 0 |
not | 참거짓 뒤집기 | not (x >= 70) |
in | 안에 있나 | grade in ("A", "B") |
🚨 가장 흔한 실수 —
=(대입)와==(비교)를 혼동.if x = 5:는 SyntaxError입니다. 비교는 반드시 등호 두 개.
💻 코드 — 성적 등급 판정기 (중첩 조건 종합)
Python — K-1: 조건문 종합 실습
def grade_calc(score, attendance):
"""점수와 출석률로 등급을 매깁니다.
비유:
학사 규정집처럼 위에서부터 조건을 하나씩 대조해 내려갑니다."""
# ① 범위 체크 (or 로 하나라도 벗어나면)
if score < 0 or score > 100 or attendance < 0 or attendance > 100:
return "입력 값이 유효 범위를 벗어났습니다."
# ② 과락 먼저 판정 (중첩 조건)
if score < 40:
return "결과: 불합격 (과락)"
# ③ 다중 조건으로 등급 산정 (위에서부터 순서대로!)
if score >= 90 and attendance >= 80:
grade = "A"
elif score >= 80 and attendance >= 75:
grade = "B"
elif score >= 70 and attendance >= 70:
grade = "C"
elif score >= 60:
grade = "D"
else:
grade = "F"
# ④ 추가 태그 (in 과 not 활용)
tag = ""
if grade in ("A", "B") and attendance >= 90:
tag = " (우수)"
elif grade == "D" and not (attendance >= 70):
tag = " (출석 경고)"
return f"점수: {score}, 출석률: {attendance}% / 최종 등급: {grade}{tag}"
for s, att in [(95, 92), (85, 70), (65, 60), (30, 95)]:
print(grade_calc(s, att))
🔗 GitHub에서 코드 보기 — 02_03_control_flow.py L12–L48
▶ 실행 결과
점수: 95, 출석률: 92% / 최종 등급: A (우수)
점수: 85, 출석률: 70% / 최종 등급: C
점수: 65, 출석률: 60% / 최종 등급: D (출석 경고)
결과: 불합격 (과락)
✅ 실행 결과 요약 — 두 번째 줄을 주목하세요
점수 85점인데 B가 아니라 C가 나왔습니다. 왜일까요? 출석률이 70%라 B의 조건(75% 이상)을 못 채웠기 때문입니다.\
🔑 elif는 위에서부터 순서대로 검사하고, 처음 맞는 것 하나만 실행한 뒤 나머지는 건너뜁니다. 그래서 조건의 순서가 결과를 바꿉니다.
🔗 ReLU가 바로 조건문입니다: if x > 0: return x else: return 0\
🔗 조기 종료: if val_loss > best_loss: patience += 1\
🔗 로그 출력: if epoch % 50 == 0: print(...) (01-13에서 본 그 줄!)\
NumPy에서는 np.where(조건, 참일때, 거짓일때)로 배열 전체에 조건문을 한 번에 적용합니다(7부 AA단원 · A~AG 단원표는 #33 참고).
⭐ 오늘의 한 줄 — elif는 "처음 맞는 하나만" 실행합니다. 조건의 순서가 곧 우선순위입니다.
🔍 더 쉽게 이해하기 — 🎢 놀이기구와 컨베이어 벨트
🎢 while = "조건이 참인 동안 계속" → 놀이기구가 정지 버튼 누를 때까지 돎\
🏭 for = "이 목록의 각 항목마다" → 컨베이어 벨트 위 물건 개수만큼 처리\
\
📌 고르는 법 — 몇 번 돌지 아는가?\
· 안다 (리스트 개수, range) → for\
· 모른다 (사용자가 그만둘 때까지) → while
💻 코드 — while 반복문
Python — L-1: while
guest = 1
while guest < 4: # guest가 4 미만인 동안 반복
print("손님이 {} 명 입니다.".format(guest))
guest = guest + 1 # ⚠️ 이 줄이 없으면 무한 루프!
if guest == 4:
print("손님이 꽉 찼습니다.")
# 1부터 100까지의 합
num, hap = 1, 0
while num <= 100:
hap += num # hap = hap + num 의 줄임
num += 1
print("1~100 합:", hap)
🔗 GitHub에서 코드 보기 — 02_03_control_flow.py L52–L64
▶ 실행 결과
손님이 1 명 입니다.
손님이 2 명 입니다.
손님이 3 명 입니다.
손님이 꽉 찼습니다.
1~100 합: 5050
🚨 무한 루프 주의 — while 안에서 조건을 바꾸는 줄(
guest += 1)을 빼먹으면 프로그램이 영원히 멈추지 않습니다. 그럴 땐 Ctrl + C로 강제 종료하세요.
💻 코드 — for 반복문과 도우미 함수들
Python — L-2: for · range · enumerate · zip
# ── range(시작, 끝, 간격) : 끝은 포함 안 함! ──
for i in range(1, 6):
print(i, end=' ') # end=' ' → 줄바꿈 대신 공백
print()
# ── enumerate() : 번호와 값을 함께 꺼내기 ──
langs = ["한국어", "English", "日本語"]
for i, lang in enumerate(langs, start=1): # start=1 → 1번부터
print(f"{i}. {lang}")
# ── zip() : 두 목록을 짝지어 꺼내기 ──
days = ["Mon", "Tue", "Wed"]
food = ["Pasta", "Steak", "Cheese", "Toast"]
print(list(zip(days, food))) # 짧은 쪽(3개)에 맞춰짐!
# ── 중첩 반복문: 구구단 ──
for i in range(2, 4):
for j in range(1, 4):
print("{} X {} = {}".format(i, j, i*j), end=' ')
print()
🔗 GitHub에서 코드 보기 — 02_03_control_flow.py L68–L87
▶ 실행 결과
1 2 3 4 5
1. 한국어
2. English
3. 日本語
[('Mon', 'Pasta'), ('Tue', 'Steak'), ('Wed', 'Cheese')]
2 X 1 = 2 2 X 2 = 4 2 X 3 = 6
3 X 1 = 3 3 X 2 = 6 3 X 3 = 9
🚦 continue와 break — 흐름 제어의 두 신호등
| ⏭️ continue | 🛑 break | |
|---|---|---|
| 하는 일 | 현재 반복만 중단하고 다음으로 | 반복문을 완전히 탈출 |
| 비유 | 🚌 버스가 이번 정류장은 통과하고 계속 달림 | 🚏 버스가 종점이라며 승객을 다 내리게 함 |
Python — L-3: continue / break
# continue : 짝수는 건너뛰고 홀수만 더하기
hap = 0
for i in range(1, 100):
if i % 2 == 0:
continue # 짝수면 아래를 건너뛰고 다음 i로
hap += i
print("1~99 홀수의 합:", hap)
# break : 조건을 만나면 즉시 탈출
for i in range(1, 100):
if i * i > 50:
print(f"제곱이 50을 넘는 첫 수: {i}")
break # 찾았으니 더 볼 필요 없음
🔗 GitHub에서 코드 보기 — 02_03_control_flow.py L91–L103
▶ 실행 결과
1~99 홀수의 합: 2500
제곱이 50을 넘는 첫 수: 8
✨ 컴프리헨션 — 묶어쓰기와 풀어쓰기
🔍 더 쉽게 이해하기 — 📝 문장 요약
"1부터 5까지 각 숫자에 5를 더해서 목록을 만들어라"를 4줄로 쓸 수도, 1줄로 쓸 수도 있습니다.\
📖 풀어쓰기 = 초보자에게 명확, 디버깅 쉬움\
⚡ 묶어쓰기(컴프리헨션) = 짧고 빠름, 파이썬다움\
중요: 둘 다 자유자재로 쓸 수 있어야 합니다. 남의 코드는 묶어쓰기로 되어 있고, 내가 디버깅할 땐 풀어쓰기가 편하기 때문입니다.
Python — L-4: 컴프리헨션 비교
# ── 풀어쓰기 ──
result = []
for num in range(1, 6):
result.append(num + 5)
print("풀어쓰기:", result)
# ── 묶어쓰기 (똑같은 일을 한 줄로!) ──
result2 = [num + 5 for num in range(1, 6)]
print("묶어쓰기:", result2)
# ── 조건 붙이기: 짝수만 골라 3배 ──
evens = [num * 3 for num in range(1, 11) if num % 2 == 0]
print("짝수×3 :", evens)
# ── 딕셔너리 컴프리헨션도 됩니다 ──
squares = {n: n**2 for n in range(1, 5)}
print("제곱 사전:", squares)
🔗 GitHub에서 코드 보기 — 02_03_control_flow.py L107–L123
▶ 실행 결과
풀어쓰기: [6, 7, 8, 9, 10]
묶어쓰기: [6, 7, 8, 9, 10]
짝수×3 : [6, 12, 18, 24, 30]
제곱 사전: {1: 1, 2: 4, 3: 9, 4: 16}
🖼️ 시각화 — 컴프리헨션 읽는 순서

🔗 에폭 루프: for epoch in range(300): — 01-13에서 본 그 줄\
🔗 배치 순회: for x, t in zip(X, T): — 입력과 정답을 짝지어\
🔗 손실 기록: losses = [compute_loss(e) for e in epochs]\
🔗 파라미터 초기화: [np.zeros(n) for n in sizes]
⭐ 오늘의 한 줄 — 묶어쓰기와 풀어쓰기를 자유자재로. 이 둘의 반복 훈련이 파이썬 실력의 절반입니다.
🔜 다음 부 예고 — 02-04. 🧠 4부 — 함수와 메모리: 파이썬의 심장
반복과 조건을 익혔으니, 이제 코드를 함수로 묶어 재사용할 차례입니다. 스코프·뮤터블·클로저까지 — 역전파 코드가 왜 중간값을 저장해야 하는지가 여기서 보입니다.
📂 이 장의 코드 폴더: book/02-hello-python/02-03-control-flow
책에 실린 코드를 장(절)별로 모아 둔 폴더입니다. 아래 파일을 열어 보거나, Colab에서 바로 실행해 보세요.
| 파일 | 용도 | 링크 |
|---|---|---|
02_03_control_flow.py | 책의 코드 블록 5개를 순서대로 모은 실행 스크립트 (# %% 셀 구분) | 코드 보기 |
02_03_control_flow.ipynb | 같은 코드를 블록당 셀 1개로 담은 주피터 노트북 | 보기 · Colab |
README.md | 코드 블록 목록 · 실행 방법 · 검증 결과 | 보기 |
🧪 저장소 검증 상태: ✅ 실행 OK
📄 02_03_control_flow.py L12–L48 · Block 1 (02-03-K 조건문 — 갈림길에서 길 고르기)
def grade_calc(score, attendance):
"""점수와 출석률로 등급을 매깁니다.
비유:
학사 규정집처럼 위에서부터 조건을 하나씩 대조해 내려갑니다."""
# ① 범위 체크 (or 로 하나라도 벗어나면)
if score < 0 or score > 100 or attendance < 0 or attendance > 100:
return "입력 값이 유효 범위를 벗어났습니다."
# ② 과락 먼저 판정 (중첩 조건)
if score < 40:
return "결과: 불합격 (과락)"
# ③ 다중 조건으로 등급 산정 (위에서부터 순서대로!)
if score >= 90 and attendance >= 80:
grade = "A"
elif score >= 80 and attendance >= 75:
grade = "B"
elif score >= 70 and attendance >= 70:
grade = "C"
elif score >= 60:
grade = "D"
else:
grade = "F"
# ④ 추가 태그 (in 과 not 활용)
tag = ""
if grade in ("A", "B") and attendance >= 90:
tag = " (우수)"
elif grade == "D" and not (attendance >= 70):
tag = " (출석 경고)"
return f"점수: {score}, 출석률: {attendance}% / 최종 등급: {grade}{tag}"
for s, att in [(95, 92), (85, 70), (65, 60), (30, 95)]:
print(grade_calc(s, att))
▶ 실행 결과 — 위 코드를 실행한 출력 (직접 실행: Linux · Python 3.13.5 · numpy 2.5.3, 앞 블록부터 순서대로 실행)
점수: 95, 출석률: 92% / 최종 등급: A (우수)
점수: 85, 출석률: 70% / 최종 등급: C
점수: 65, 출석률: 60% / 최종 등급: D (출석 경고)
결과: 불합격 (과락)
📄 02_03_control_flow.py L107–L123 · Block 5 (02-03-L 반복문과 컴프리헨션 — 묶어쓰기와 풀어쓰기 — 풀어쓰기)
# ── 풀어쓰기 ──
result = []
for num in range(1, 6):
result.append(num + 5)
print("풀어쓰기:", result)
# ── 묶어쓰기 (똑같은 일을 한 줄로!) ──
result2 = [num + 5 for num in range(1, 6)]
print("묶어쓰기:", result2)
# ── 조건 붙이기: 짝수만 골라 3배 ──
evens = [num * 3 for num in range(1, 11) if num % 2 == 0]
print("짝수×3 :", evens)
# ── 딕셔너리 컴프리헨션도 됩니다 ──
squares = {n: n**2 for n in range(1, 5)}
print("제곱 사전:", squares)
▶ 실행 결과 — 위 코드를 실행한 출력 (직접 실행: Linux · Python 3.13.5 · numpy 2.5.3, 앞 블록부터 순서대로 실행)
풀어쓰기: [6, 7, 8, 9, 10]
묶어쓰기: [6, 7, 8, 9, 10]
짝수×3 : [6, 12, 18, 24, 30]
제곱 사전: {1: 1, 2: 4, 3: 9, 4: 16}
👉 Open in Colab — 02_03_control_flow.ipynb · 설치 없이 브라우저에서 셀을 위에서부터 순서대로 실행하세요.
git clone https://github.com/otoloism/Zero_to_ML_Master.git
cd Zero_to_ML_Master
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r book/requirements.txt # 책 전체용 (PyTorch 등 포함, 용량 큼)
cd book/02-hello-python/02-03-control-flow
python 02_03_control_flow.py
⭐ 코드가 도움이 되셨다면 GitHub 저장소에 Star를 눌러 주세요. 새 장의 코드가 올라올 때 가장 먼저 알 수 있습니다.
🍴 직접 고쳐 보며 실험하고 싶다면 Fork 해서 내 저장소에서 마음껏 바꿔 보세요. 오류 제보·개선 제안은 Issues로 환영합니다!
다음 글은 02-04 🧠 4부 — 함수와 메모리: 파이썬의 심장 입니다. 반복과 조건을 익혔으니, 코드를 함수로 묶어 재사용할 차례예요. 스코프·뮤터블·클로저까지 — 역전파 코드가 왜 중간값을 저장해야 하는지가 여기서 보입니다.
⬅️ 이전 글: #35 파이썬 자료형 완전 정복 — 변수는 이름표, list·tuple·dict·set 고르는 법과 형변환·초보자 3대 에러 (02권 2부) \
➡️ 다음 글: #37 파이썬 함수와 메모리 — 스코프·UnboundLocalError·뮤터블 인자부터 GIL·클로저·데코레이터까지 (02권 4부)
이 시리즈는 수학을 놓았던 비전공자가 AI를 직접 구현하기까지의 공부 기록을 그대로 옮긴 연재입니다. 원문 책, 코드, 개념 사전을 함께 보면 훨씬 빨리 늡니다. 🚀
| 바로가기 | 이런 분께 | |
|---|---|---|
| 📘 책 (위키독스, 무료) | Zero to 머신러닝 딥러닝 Master | 5권 · 20개 장 · 163개 절 전체를 순서대로 읽고 싶은 분 |
| 📄 이 글의 원문 | 02-03 🔁 3부 — 흐름 제어: 조건과 반복 | 연습문제·해설까지 전부 보고 싶은 분 |
| 💻 실습 코드 (GitHub) | otoloism/Zero_to_ML_Master | .py·.ipynb를 Colab에서 바로 돌려보고 싶은 분 |
| 🏠 머신러닝 백과사전 | mldict.net | 본문 속 핵심 개념을 카드로 다시 확인하고 싶은 분 |
| ✍️ 기술 블로그 | wikidocs.net/blog/@mldict | 새 글 알림을 가장 먼저 받고 싶은 분 |
⭐ 도움이 되셨다면 velog 팔로우와 GitHub Star를 눌러 주세요. 다음 글을 쓰는 가장 큰 힘이 됩니다. 궁금한 점은 댓글로 편하게 남겨 주세요! 🙌