break·continue·pass의 정확한 동작과 파이썬 고유의 for-else 패턴을 마스터한다.
🎯 이 강의에서 배우는 것
파이썬의 루프 제어 키워드인 break, continue, pass와 파이썬 고유의 for-else / while-else 패턴을 완전히 이해합니다. 특히 for-else는 다른 언어에는 없는 파이썬만의 구문으로, 탐색 루프를 우아하게 표현하는 강력한 도구입니다.
🛑 break — 루프 즉시 탈출
# break는 자신이 속한 루프 하나만 종료
nums = [3, 7, -2, 5, 9, -1]
# 첫 번째 음수 위치 찾기
for i, n in enumerate(nums):
if n < 0:
print(f"첫 음수: 인덱스 {i}, 값 {n}")
break # 찾았으니 더 볼 필요 없음
# "첫 음수: 인덱스 2, 값 -2"
# break 없이 짰을 때의 문제
found_idx = -1
for i, n in enumerate(nums):
if n < 0:
found_idx = i
break # 없으면 마지막 음수를 저장 (잘못된 결과)
# 중첩 루프에서 break: 자신이 속한 루프만 종료
for i in range(3):
for j in range(3):
if j == 1:
break # 안쪽 루프만 종료
print(f"({i},{j})", end=" ")
print()
# (0,0)
# (1,0)
# (2,0)
🔀 중첩 루프 전체 탈출 전략
matrix = [[1, 0, 3], [4, 5, 0], [7, 8, 9]]
# 방법 1: flag 변수 (단점: 루프마다 flag 체크 필요)
found = False
for i in range(len(matrix)):
for j in range(len(matrix[i])):
if matrix[i][j] == 0:
found = True
break
if found:
break
print(f"flag 방법: ({i},{j})")
# 방법 2: 함수로 감싸서 return (권장 — 가장 명확)
def find_zero(matrix):
for i, row in enumerate(matrix):
for j, val in enumerate(row):
if val == 0:
return (i, j) # 즉시 함수 종료
return None # 없으면 None
result = find_zero(matrix)
print(f"함수 방법: {result}") # (0, 1)
# 방법 3: 예외 던지기 (극단적 상황에만)
class FoundException(Exception):
def __init__(self, row, col):
self.row, self.col = row, col
try:
for i, row in enumerate(matrix):
for j, val in enumerate(row):
if val == 0:
raise FoundException(i, j)
except FoundException as e:
print(f"예외 방법: ({e.row},{e.col})")
⏭️ continue — 이번 반복 건너뛰기
# continue는 현재 iteration의 나머지를 건너뛰고 다음 iteration으로
for i in range(10):
if i % 2 == 0:
continue # 짝수 건너뜀
print(i, end=" ") # 1 3 5 7 9
print()
# 필터링 패턴: continue로 중첩 줄이기
# 나쁜 예 (깊은 중첩)
data = [{"name": "홍길동", "age": 25, "active": True},
{"name": "이순신", "age": 17, "active": True},
{"name": "강감찬", "age": 30, "active": False}]
results_bad = []
for user in data:
if user["active"]:
if user["age"] >= 18:
results_bad.append(user["name"])
# 좋은 예: continue로 평탄하게
results_good = []
for user in data:
if not user["active"]:
continue # 비활성 건너뜀
if user["age"] < 18:
continue # 미성년자 건너뜀
results_good.append(user["name"])
print(results_good) # ['홍길동']
# while 루프에서 continue
n = 0
while n < 20:
n += 1
if n % 3 == 0 or n % 5 == 0:
continue # 3의 배수나 5의 배수 건너뜀
print(n, end=" ") # 3, 5, 6... 이 아닌 나머지
print()
🐍 for-else / while-else — 파이썬 고유의 패턴
else 블록은 break 없이 루프가 정상 종료됐을 때만 실행됩니다. "끝까지 탐색했는데 못 찾았을 때" 처리에 최적입니다:
# 소수 판별 — for-else의 교과서적 활용
def is_prime(n):
if n < 2:
return False
for divisor in range(2, int(n**0.5) + 1):
if n % divisor == 0:
# 나눠지면 소수가 아님 → break로 루프 탈출
break
else:
# break 없이 루프 완료 → 소수!
return True
return False
for num in [2, 3, 4, 17, 20, 97]:
print(f"{num}: {'소수' if is_prime(num) else '합성수'}")
# 2: 소수, 3: 소수, 4: 합성수, 17: 소수, 20: 합성수, 97: 소수
# 탐색 패턴 비교
# for-else 없이 (flag 변수 필요)
def find_user_flag(users, name):
found = False
for user in users:
if user["name"] == name:
found = True
print(f"찾음: {user}")
break
if not found:
print(f"{name}를 찾지 못함")
# for-else 사용 (더 파이썬답고 명확)
def find_user(users, name):
for user in users:
if user["name"] == name:
print(f"찾음: {user}")
break
else:
print(f"{name}를 찾지 못함")
users = [{"name": "홍길동", "score": 85}]
find_user(users, "홍길동") # 찾음: {'name': '홍길동', 'score': 85}
find_user(users, "없는사람") # 없는사람를 찾지 못함
# while-else: 재시도 로직
import random
random.seed(42)
attempt = 0
while attempt < 3:
attempt += 1
value = random.randint(1, 5)
print(f"시도 {attempt}: {value}")
if value == 3:
print("성공!")
break
else:
print("3번 시도 모두 실패")
🔇 pass와 Ellipsis(...)
# pass: 문법적으로 블록이 필요하지만 아무것도 안 할 때
class EmptyClass:
pass # 빈 클래스 (나중에 내용 추가 예정)
def todo_function():
pass # 나중에 구현할 함수
# 조건문에서 특정 경우를 무시할 때
for i in range(10):
if i % 2 == 0:
pass # 짝수는 일단 무시 (나중에 처리 추가 예정)
else:
print(i, end=" ")
print()
# Ellipsis (...): pass와 비슷하지만 의미가 다름
# 타입 힌트에서 미완성 stub 표시
def not_implemented() -> int:
... # "아직 구현 안 했음"을 명시적으로 표현
# 타입 힌트에서 Callable 표시
from typing import Callable
def apply(func: Callable[..., int], x: int) -> int:
return func(x)
# numpy 슬라이싱
# import numpy as np
# arr[..., 0] ← "나머지 모든 차원"의 뜻
# 결론: 구문적으로 블록 채우기 → pass / 미완성 타입/stub → ...
🔁 실전 패턴 — try-except-continue
# 데이터 처리에서 오류 있는 항목만 건너뛰기
raw_data = ["10", "20", "abc", "30", "xyz", "50"]
valid_nums = []
for item in raw_data:
try:
valid_nums.append(int(item))
except ValueError:
print(f"건너뜀: {item!r}")
continue # 오류 항목 건너뛰고 다음으로
print(valid_nums) # [10, 20, 30, 50]
# 파일 읽기에서 빈 줄 건너뛰기 패턴
lines = ["# 제목", "", " ", "내용 1", "", "내용 2"]
for line in lines:
stripped = line.strip()
if not stripped: # 빈 줄 건너뜀
continue
if stripped.startswith("#"): # 주석 건너뜀
continue
print(f"처리: {stripped}")
# "처리: 내용 1"
# "처리: 내용 2"
⚠️ 자주 하는 실수
- break와 continue 혼동: break는 루프를 완전히 종료, continue는 현재 반복만 건너뛰고 루프 계속. 대부분의 "건너뛰기"에는 continue를, "탐색 완료"에는 break를 사용하세요.
- for-else를 if-else처럼 이해: else는 if에 대응하는 것이 아니라 break 없이 루프가 끝났을 때만 실행됩니다. return이나 예외로 루프를 나가도 else는 실행됩니다.
- 중첩 루프에서 break 범위 오해: break는 자신이 직접 속한 루프만 종료합니다. 전체 탈출이 필요하면 함수로 감싸고 return을 사용하세요.
📝 정리 및 다음 강의 예고
break: 자신이 속한 루프 즉시 종료. 중첩 루프 전체 탈출은 함수+return을 사용하세요.continue: 현재 반복 건너뜀. 필터링 로직에서 중첩을 줄이는 데 효과적입니다.for-else: break 없이 루프 완료 시 else 실행. 탐색 실패 처리에 최적입니다.pass: 문법 요건을 채우는 빈 블록....는 미완성 stub을 명시적으로 표현합니다.
다음 강의: 리스트 컴프리헨션, 딕셔너리·셋 컴프리헨션, 제너레이터 표현식 — 파이썬다운 표현의 정수를 배웁니다.
관련 주제
- break·continue 차이
- for-else 패턴
- while-else 패턴
- pass와 Ellipsis
- 중첩루프 탈출
- 소수 판별 예제
- 개발·프로그래밍
- 개발·프로그래밍 강의
- 파이썬 기초 40강 — 처음 배우는 프로그래밍
- 무료강의
- 무료 온라인 강의
- NUGUNA
- 누구나
📚 시리즈 전체 공유
파이썬 기초 40강 — 처음 배우는 프로그래밍
이 강의가 속한 시리즈는 총 32강, 모두 무료입니다. 처음부터 배우려는 동료에게 시리즈 전체를 알려 주세요.
댓글
0/1000
불러오는 중...
