C.W.K.
Stream
Lesson 03 of 07 · published

for 와 while — 반복문, else 절, break/continue

~20 min · for, while, loop, else-on-loop

Level 0호기심
0 XP0/93 lessons0/23 achievements
0/100 XP to next level100 XP to go0% complete

for-each 야, for-i 가 아니야

Python 의 for 는 iterable 위의 foreach, C 스타일 인덱스 카운터가 아니야. for x in seq:x 를 각 원소에 바인딩. "for i in 0 to n" 같은 거 없어. 인덱스가 필요하면 range(n). 인덱스랑 값 둘 다 필요하면 enumerate(seq). 이거 한번 익히면 머릿속에서 C 스타일 for 를 변환하는 거 멈춰.

enumerate / zip / reversed — 반복 삼총사

enumerate(seq)(인덱스, 값) 페어 yield. zip(a, b, ...) 은 각 iterable 의 원소를 튜플로 짝지어, 가장 짧은 거 끝나면 멈춤. reversed(seq) 는 역순 yield. 조합하면 — for i, (a, b) in enumerate(zip(list1, list2)):. 이 셋이 수동 인덱스 관리 장르 전체를 대체.

while — "뭔가 될 때까지" 의 일꾼

반복 횟수가 미리 안 정해질 때 while. 입력이 매치할 때까지, 조건 만족까지, 큐가 빌 때까지. 3.8+ 의 walrus 연산자 := 가 read-and-test 패턴에 좋아 — while (line := f.readline()):. while True: + 수동 break 손에 닿기 전에 — 조건 직접 while 에 박을 수 있는지 봐.

break / continue / 잘 안 알려진 else

break — 가장 안쪽 loop 종료. continue — 다음 iteration 으로. 이상한 놈 — loop 의 else. else 블록은 loop 가 *break 없이 완주* 했을 때 실행. "뭔가 찾는 중 — 못 찾으면 X 해라" 패턴에 완벽. 처음엔 이상하게 읽혀. 한 번 알면 flag 변수를 깔끔히 대체할 수 있어.

주의: 순회하면서 list 변경하면 버그 자석. 안전한 방법 — 사본 순회 (for x in items[:]) 또는 컴프리헨션으로 새 list 만들고 끝에 교체.
Pythonic Way: for i in range(len(seq)) 쓰는 자신을 발견하면 멈추고 enumerate(seq). range(len()) 이 맞는 유일한 경우는 *값이 진짜로 안 필요할 때* — 그래도 왜 그런지 자문해봐.

Code

iterable 위의 for-each·python
fruits = ["apple", "banana", "cherry"]

# 값 순회
for f in fruits:
    print(f)

# 인덱스 같이 — range(len()) 쓰지 말고
for i, f in enumerate(fruits):
    print(i, f)

# 시작 인덱스 커스텀
for i, f in enumerate(fruits, start=1):
    print(i, f)
# 1 apple
# 2 banana
# 3 cherry
zip — 페어 / 트리플 / 쿼드러플·python
names = ["alice", "bob", "charlie"]
ages = [30, 25, 35]

for name, age in zip(names, ages):
    print(f"{name} is {age}")

# zip 은 가장 짧은 거에서 멈춤
tickers = ["AAPL", "MSFT", "GOOG", "NVDA"]
prices = [180, 420, 145]
for t, p in zip(tickers, prices):
    print(t, p)
# 3 페어만 출력 — NVDA 는 떨어짐

# zip(strict=True) 는 길이 다르면 raise — 3.10+
try:
    for t, p in zip(tickers, prices, strict=True):
        pass
except ValueError as e:
    print(e)
while + walrus — read-and-test·python
import io
# 파일인 척
f = io.StringIO("line1\nline2\nline3\n")

# 옛 어색한 스타일
# while True:
#     line = f.readline()
#     if not line:
#         break
#     process(line)

# 3.8+ walrus — 깔끔
while (line := f.readline()):
    print("got:", line.strip())
# got: line1
# got: line2
# got: line3
loop 의 else — break 없을 때 실행·python
def find_negative(items):
    for i, x in enumerate(items):
        if x < 0:
            print(f"first negative at index {i}")
            break
    else:
        print("음수 없음")

find_negative([1, 2, 3])         # 음수 없음
find_negative([1, -2, 3])        # first negative at index 1

# else 는 while 에서도
n = 100
while n > 1:
    if n % 2 == 1:                # 홀수
        print("홀수 만남")
        break
    n //= 2
else:
    print("홀수 없이 끝까지 반")
# 홀수 없이 끝까지 반
순회 중 변경 버그 — 안전한 대안·python
items = [1, 2, 3, 4, 5, 6]

# 위험 — 이상한 동작, 원소 건너뛸 수 있음
# for x in items:
#     if x % 2 == 0:
#         items.remove(x)

# 안전 1 — 슬라이스 사본 순회
items = [1, 2, 3, 4, 5, 6]
for x in items[:]:
    if x % 2 == 0:
        items.remove(x)
print(items)              # [1, 3, 5]

# 안전 2 — 컴프리헨션으로 새 list
items = [1, 2, 3, 4, 5, 6]
items = [x for x in items if x % 2 != 0]
print(items)              # [1, 3, 5]

External links

Exercise

병렬 list 두 개 — tickers = ["AAPL", "MSFT", "GOOG", "NVDA"], prices = [180, 420, 145, 950]. (a) enumerate + zip 으로 각 ticker + price 출력. (b) 200 미만 가격의 첫 ticker 찾아서 이름 출력 + break. 못 찾으면 loop else 절로 'all expensive' 출력. (c) while + walrus 로 "pippa" 의 각 글자를 한 번에 하나씩 출력 — iternext 써 (it = iter("pippa"); while (ch := next(it, None)):).

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.