본문으로 건너뛰기

for와 range

파이썬 목차반복레슨 19 / 59

목차

for 문은 값을 하나씩 꺼내 그 값에 이름을 붙이고, 꺼낼 때마다 들여 쓴 덩어리를 한 번 실행합니다. range(시작, 끝)은 시작부터 끝 바로 앞까지의 수를 차례로 내줍니다.

while로 1부터 3까지 세려면 시작 값 두기, 조건, 1 더하기 세 줄을 챙겨야 합니다. 하나만 빠뜨려도 반복이 끝나지 않거나 틀린 수를 셉니다. for와 range는 이 세 가지를 한 줄에 담습니다. 대신 끝 수는 넣지 않는다는 규칙 하나를 익혀야 합니다.

10단계 중 1단계. 다음을 누르면 1번 줄부터 실행합니다.

1for는 값을 하나씩 꺼내 그 값에 이름을 붙인다

앞 레슨의 while로 1부터 3까지 찍는 코드입니다. 시작 값(1번 줄), 조건(2번 줄), 1 더하기(4번 줄)를 직접 씁니다.

i = 1
while i < 4:
    print(i)
    i = i + 1
print('끝')
실행 결과
1
2
3
끝

같은 일을 for와 range로 쓰면 이렇습니다.

for i in range(1, 4):
    print(i)
print('끝')
실행 결과
1
2
3
끝

for 다음에 이름을, in 다음에 꺼낼 값들을 쓰고 콜론(:)으로 끝냅니다. 덩어리는 while처럼 4칸 들여 씁니다. 파이썬은 이 코드를 이렇게 실행합니다.

  1. 1번 줄: range(1, 4)에서 첫 수 1을 꺼내 그 값에 이름 i를 붙입니다.
  2. 2번 줄: 덩어리를 한 번 실행해 1을 찍습니다.
  3. 덩어리 끝에서 1번 줄로 돌아가 다음 수 2를 꺼내 그 값에 i를 다시 붙이고, 덩어리를 실행합니다. 3도 같습니다.
  4. 1번 줄에 다시 왔을 때 더 꺼낼 수가 없으면 반복을 끝내고 3번 줄로 갑니다.

while 코드가 직접 하던 시작 값 두기와 1 더하기를 for가 맡고, 언제 멈출지는 range가 내주는 수가 정합니다(규칙 4).

2range는 끝 수를 넣지 않는다

아래 코드는 무엇을 찍을까요? 답을 정한 뒤 펼쳐 보세요.

for i in range(3):
    print(i)
실행 결과 보기
실행 결과
0
1
2

예상과 다르면 그곳이 배울 곳입니다. range에 수를 하나만 쓰면 그 수가 끝이고 시작은 0입니다. 끝 수 3은 넣지 않으므로 0, 1, 2 세 수를 내줍니다.

range(시작, 끝)도 같은 규칙입니다. 시작은 넣고 끝은 넣지 않습니다. 그래서 시작이 끝보다 작으면 내주는 수의 개수는 끝 − 시작입니다.

쓴 것내주는 수개수
range(3)0, 1, 23
range(1, 4)1, 2, 33
range(2, 5)2, 3, 43
range(1, 11)1, 2, …, 1010

1부터 10까지 돌리려면 끝 자리에 하나 큰 11을 씁니다. range에는 정수만 넣을 수 있습니다. 실수를 넣으면 어떻게 되는지는 예제에서 봅니다.

3문자열은 한 글자씩 꺼낸다

in 다음에 문자열을 두면 for는 글자를 하나씩 꺼냅니다. 이름 ch는 글자(character)를 줄인 이름입니다.

for ch in '라테':
    print(ch)
실행 결과
라
테

꺼내는 값이 수에서 글자로 바뀌었을 뿐, 하는 일은 같습니다. 값을 하나씩 꺼내 그 값에 이름을 붙이고 덩어리를 한 번 실행합니다. 빈칸도 한 글자로 꺼냅니다.

예제

대기 번호 부르기

주문한 음료가 나오면 대기 번호를 차례로 부릅니다. f-문자열의 {n} 자리에 꺼낸 번호가 들어갑니다.

for n in range(1, 4):
    print(f'{n}번 손님')
실행 결과
1번 손님
2번 손님
3번 손님

range에 실수를 넣으면

쿠키 6개를 2명이 나눠 가질 때 한 사람 몫만큼 반복하려 했습니다.

each = 6 / 2
for i in range(each):
    print(i)
실행 결과
Traceback (most recent call last):  File "main.py", line 2, in <module>    for i in range(each):             ~~~~~^^^^^^TypeError: 'float' object cannot be interpreted as an integer

맨 아래 줄부터 읽습니다. TypeError는 값의 종류가 맞지 않는다는 오류이고, 설명은 '실수(float)는 정수로 쓸 수 없다'는 뜻입니다. 오류는 2번 줄에서 났지만 실수를 만든 곳은 1번 줄입니다. /는 나누어떨어져도 늘 실수를 냅니다(6 / 2는 3.0). 몫을 내는 //로 each = 6 // 2라고 쓰면 0, 1, 2가 찍힙니다.

자주 틀리는 곳

틀린 생각: range(1, 4)에는 끝 수 4도 든다.

말로 '1부터 4까지'라고 하면 4도 넣으니, 두 수를 쓴 range(1, 4)도 그렇게 읽힙니다. range는 끝 수를 넣지 않습니다.

1절 코드는 1, 2, 3만 찍습니다. 인덱스와 자르기의 s[1:3]이 끝 번호 3의 글자를 넣지 않는 것과 같은 규칙입니다.

맞는 규칙: range(시작, 끝)은 시작은 넣고 끝은 넣지 않아, 시작이 끝보다 작으면 끝 − 시작 개의 수를 내줍니다. 1부터 n까지 돌리려면 range(1, n + 1)처럼 끝을 하나 크게 씁니다.

틀린 생각: range(3)은 1부터 센다.

사람은 수를 셀 때 1부터 세니, 수 하나만 쓴 range(3)도 1, 2, 3으로 읽힙니다. 시작을 쓰지 않으면 0부터입니다.

2절 코드는 0, 1, 2를 찍습니다. 개수는 3개로 같습니다.

맞는 규칙: range(끝)은 range(0, 끝)과 같아서 0부터 끝 바로 앞까지 내줍니다. 1부터 세려면 range(1, 4)처럼 시작을 씁니다.

틀린 생각: 반복이 끝나면 for의 이름은 사라지거나 끝 수에 붙는다.

for 줄에서 생긴 이름이라 반복과 함께 없어지거나, 끝 수까지 세고 멈췄을 것 같습니다. 이름은 반복 뒤에도 남고, 끝 수에 붙은 적은 없습니다.

for i in range(3):
    print('커피')
print(i)
실행 결과
커피
커피
커피
2

range(3)이 마지막에 내준 수는 2이고, 3은 내주지 않습니다. 덩어리 안에서 i를 쓰지 않아도 for는 바퀴마다 꺼낸 수에 i를 붙입니다.

맞는 규칙: for는 바퀴마다 꺼낸 값에 이름을 다시 붙이고, 반복이 끝나도 그 이름을 지우지 않습니다. 그래서 덩어리에서 그 이름을 다시 붙이지 않았다면, 반복 뒤의 이름은 마지막에 꺼낸 값에 붙어 있습니다(규칙 3).

확인 문제

1. 예제(대기 번호)의 range(1, 4)를 range(2, 5)로 바꿨습니다. 무엇이 찍히는지 마지막 줄까지 글자 그대로 쓰세요.

for n in range(2, 5):
    print(f'{n}번 손님')
힌트

range(2, 5)가 내주는 수를 먼저 적고, 수마다 찍히는 줄을 씁니다.

정답
실행 결과
2번 손님
3번 손님
4번 손님

range(2, 5)는 2, 3, 4 세 수를 내주어 모두 3줄입니다.

흔한 오답은 넷째 줄 5번 손님까지 쓰는 것입니다. 끝 수도 든다고 본 것입니다(끝도 든다는 생각). 끝 수 5는 넣지 않습니다.

2. 아래 while 코드는 이렇게 찍습니다.

n = 5
while n < 8:
    print(n)
    n = n + 1
실행 결과
5
6
7

같은 출력이 나오도록 for 코드의 빈칸 둘을 채우세요.

for n in range(___, ___):
    print(n)
힌트

처음 찍는 수가 시작입니다. 끝 자리에 쓸 수는 while의 조건 n < 8에서 찾아봅니다.

정답

차례로 5와 8입니다.

for n in range(5, 8):
    print(n)
실행 결과
5
6
7

while의 조건 n < 8이 8을 넣지 않듯, range(5, 8)도 8을 넣지 않습니다.

흔한 오답은 range(5, 7)입니다. 마지막에 찍는 7을 끝 자리에 써서 끝 수도 든다고 본 것입니다(끝도 든다는 생각). 끝 수는 넣지 않아서 5와 6만 찍힙니다.

3. 하루에 5000걸음씩 걷습니다. 날마다 그날까지 걸은 걸음 수를 찍는 코드입니다. 줄마다 찍히는 값을 고르세요.

for day in range(1, 3):
    print(day * 5000)
  • ① 5000, 10000
  • ② 5000, 10000, 15000
  • ③ 0, 5000, 10000
힌트

range(1, 3)이 내주는 수를 먼저 적고, 수마다 day * 5000을 계산합니다.

정답
실행 결과
5000
10000

①입니다. range(1, 3)은 1, 2 두 수를 내줍니다.

  • ② 끝 수 3도 든다고 봤습니다(끝도 든다는 생각). range는 끝 수를 넣지 않습니다.
  • ③ range가 늘 0부터 센다고 봤습니다. 시작 1을 썼으므로 1부터입니다.

아래 코드 1번 줄의 range(3)을 range(2, 6)으로 바꾸면 찍히는 줄을 모두 봅니다.

처음 펼 때 약 6MB를 받습니다.컴퓨터에서 해 보기

끝까지 내려오면 저절로 표시됩니다. 이 기기에만 저장합니다.

파이썬 목차로