Skip to content

Latest commit

 

History

History

Folders and files

README.md

step04_loop — 반복문

학습 순서 4번. 원본 수업이 여기서 멈췄기 때문에 새로 작성한 챕터입니다. 코드는 현행 파이썬 스타일(f-string)로 썼습니다.

왜 여기가 중요한가

step03 까지는 프로그램이 한 번 위에서 아래로 흐르기만 했습니다. 반복문은 컴퓨터가 사람보다 잘하는 유일한 일 — 같은 일을 지치지 않고 반복하는 것 — 을 시키는 도구입니다.

데이터 분석은 결국 "많은 데이터를 하나씩 훑는" 일이라, 반복문 없이는 한 발도 나갈 수 없습니다.

학습 목표

  • for 로 정해진 횟수·정해진 대상을 반복한다
  • range() 의 세 가지 형태를 구분한다
  • while 로 "끝을 모르는" 반복을 한다
  • break / continue 로 흐름을 조절한다
  • 중첩 반복문의 실행 순서를 머릿속에 그린다
  • 파이썬 고유의 for~else 를 안다

파일 지도

파일 내용
forEx1.py ★ for 기본, range 3형태, 리스트·문자열 순회, enumerate
forEx2.py 중첩 for — 구구단
whileEx1.py while, 무한 루프와 break
breakContinue.py break / continue, 중첩에서의 동작
loopElse.py for~else
test1.py 연습문제 — 합계·짝수합·개수 세기
test2.py 연습문제 — 별 찍기 3종

실행 방법

python3 step04_loop/forEx1.py

전부 키보드 입력 없이 실행됩니다. whileEx1.py 의 입력받는 부분은 주석 처리해 두었으니 풀어서 써 보세요.

짚고 갈 지점

range() 는 끝 값을 포함하지 않는다

range(5)          # 0 1 2 3 4        — 0부터, 5는 빠진다
range(1, 6)       # 1 2 3 4 5        — 1부터 6 미만
range(1, 10, 2)   # 1 3 5 7 9        — 2씩 건너뛰며
range(5, 0, -1)   # 5 4 3 2 1        — 거꾸로

끝 값이 빠진다는 게 처음엔 계속 헷갈립니다. range(1, 11) 이어야 1~10이 나옵니다.

step03 의 randint(1, 100) 은 100을 포함했던 걸 기억하세요. range 는 포함하지 않습니다. 같은 파이썬인데 다릅니다.

for 와 while, 무엇을 쓸까

언제
for 몇 번 돌지 정해져 있을 때. 리스트를 훑을 때
while 언제 끝날지 조건으로만 알 때. 사용자가 q 를 칠 때까지 등

whileEx1.py 는 같은 1~5 출력을 두 방식으로 보여 줍니다. 이런 경우엔 for 가 짧고 안전합니다 — while 은 i += 1 을 빠뜨리면 무한 루프가 되니까요.

문자열 곱하기

print('*' * 5)     # *****
print(' ' * 3)     # 공백 3칸

파이썬은 문자열에 숫자를 곱하면 그만큼 반복합니다. test2.py 의 별 찍기가 안쪽 for 없이 한 줄로 되는 이유입니다.

피라미드 한 줄은 이렇게 나옵니다.

print(' ' * (n-i) + '*' * (2*i-1))
#      └ 왼쪽 여백 ┘   └ 별 개수 ┘

i 가 1, 2, 3... 으로 갈 때 여백은 줄고 별은 2개씩 늡니다. 종이에 표를 그려 보면 규칙이 보입니다.

end 옵션

print(i)                # 출력 후 줄바꿈 (기본값 end='\n')
print(i, end=' ')       # 줄바꿈 대신 공백 → 가로로 이어진다
print()                 # 빈 print 로 줄바꿈만

forEx2.py 의 구구단을 가로로 붙이는 부분에서 이걸 씁니다. 안쪽 for 가 끝날 때마다 print() 로 줄을 바꿉니다.

중첩 반복의 실행 순서

for i in range(2, 10):        # 바깥이 한 번 돌 때
    for j in range(1, 10):    # 안쪽은 통째로 9번 돈다
        print(i*j)

바깥 8번 × 안쪽 9번 = 72번 실행됩니다. 바깥 변수가 i, 안쪽이 j 인 관습이 여기서 나왔습니다.

break 는 자기가 속한 반복문 하나만 빠져나옵니다. breakContinue.py 의 중첩 예제에서 안쪽 break 가 바깥 for 를 멈추지 못하는 것을 확인하세요.

for~else — 이름이 오해를 부른다

for n in [7, 11, 15, 18]:
    if n % 3 == 0:
        print('찾음 :', n)
        break
else:
    print('3의 배수가 없습니다')

여기서 else 는 "조건이 거짓일 때"가 아니라 "break 없이 끝까지 다 돌았을 때" 실행됩니다. for 와 짝을 이루는 else 라기보다 break 와 짝을 이루는 else 에 가깝습니다.

"찾으면 멈추고, 끝까지 못 찾으면 알린다"는 패턴에서 유용합니다. loopElse.py 에 else 를 안 쓰고 플래그 변수로 같은 일을 하는 코드도 나란히 넣었으니 비교해 보세요.

흔한 실수

증상 원인
무한 루프 while 에서 조건에 쓰인 변수를 안 바꿈 (i += 1 누락)
1개 모자람 range(1, 10) 은 10을 포함하지 않음
IndentationError 반복할 문장을 들여쓰지 않음. 파이썬은 들여쓰기가 문법입니다
반복 후 값이 이상함 누적 변수(total = 0)를 반복문 안에서 초기화

마지막 것은 특히 자주 나옵니다.

for i in range(1, 11):
    total = 0        # ← 매번 0으로 되돌아간다. 밖으로 빼야 한다
    total += i

연습 과제

  1. forEx1.py 의 1~10 합계를 while 로 다시 쓰세요.
  2. 구구단에서 홀수 단만 출력하도록 forEx2.py 를 고치세요.
  3. 1부터 100까지 중 3의 배수이면서 5의 배수인 수를 모두 출력하세요.
  4. test2.py 에 마름모(피라미드 + 역피라미드)를 추가하세요.
  5. 사용자에게 숫자를 계속 입력받아 합계를 내다가, 0 을 입력하면 종료하고 결과를 출력하는 프로그램을 while 로 만드세요.
  6. step03_controlstmt/randomEx.py 의 로또 번호 생성을 sample() 없이 randint + while + 중복 검사로 직접 구현하세요. (sample 이 대신 해 주던 일이 무엇인지 알게 됩니다)