
이미지 출처: Pexels, Pixabay · Pexels License
7편의 장바구니에 값을 붙여 봅니다. 사과 3,000원, 우유 2,500원, 계란 6,000원, 빵 4,200원, 커피 8,900원. 계산대에서 물건이 하나씩 지나갈 때마다 합계가 올라가는 영수증을 코드로 만드는 것이 오늘 할 일입니다. 완성하면 이렇게 찍힙니다.
사과 3000 누적 3000
우유 2500 누적 5500
계란 6000 누적 11500
빵 4200 누적 15700
커피 8900 누적 24600
합계 24600
print를 여섯 줄 쓰면 지금 당장은 됩니다. 물건이 여섯 개가 되면 한 줄을 더 쓰고, 값이 바뀌면 여섯 줄을 다 고칩니다. 물건이 몇 개든 같은 코드로 끝내려면 "하나씩 꺼내서 같은 일을 반복하는" 문법이 필요합니다. 그것이 for 반복문입니다.
for는 칸을 하나씩 꺼내 주는 문법입니다
파이썬 공식 자습서는 for 문을 이렇게 정의합니다. 리스트나 문자열 같은 시퀀스의 항목들을, 그 시퀀스에 들어 있는 순서대로 하나씩 꺼내 처리하는 문장. 다른 언어의 for가 "몇 번 돌아라"에 가깝다면, 파이썬의 for는 "이 묶음에서 하나씩 꺼내라"에 가깝습니다. 그래서 횟수를 세는 변수 없이 리스트를 통째로 넘기면 됩니다.
쓰는 순간은 같은 일을 값만 바꿔 여러 번 할 때입니다. 장바구니 값 더하기, 점수 열 개 평균 내기, 문장의 글자를 한 자씩 검사하기. 개수가 몇이든 코드는 한 덩어리입니다.

for 한 줄은 네 조각입니다. 꺼낼 묶음, 담을 이름, 그리고 콜론 뒤에 들여쓴 블록. 들여쓰기가 없는 줄은 반복이 다 끝난 뒤 한 번만 실행됩니다.
성질은 넷입니다.
| 성질 | 뜻 | 아래 코드에서 |
|---|---|---|
| 순서대로 꺼낸다 | 리스트에 든 순서 그대로, 앞에서 뒤로 | 사과 → 우유 → 계란 → 빵 → 커피 |
| 이름이 매번 바뀐다 | item에 이번 차례 값이 새로 담긴다 | 첫 바퀴 item은 사과, 둘째 바퀴는 우유 |
| 블록만 반복된다 | 콜론 뒤 들여쓴 줄만 매번 돈다. 6편 if의 들여쓰기 규칙 그대로 | print(item)은 다섯 번, print("끝")은 한 번 |
| 묶음은 리스트가 아니어도 된다 | 문자열, range, 나중에 배울 딕셔너리도 돈다 | for ch in "빵", for n in range(5) |
앞으로 이 뜻으로 쓰는 낱말입니다.
| 용어 | 뜻 |
|---|---|
| 반복문(loop) | 같은 블록을 여러 번 실행시키는 문장. for와 while 둘 |
| 반복 변수 | for item in cart의 item. 매 바퀴 새 값이 담기는 이름 |
| 시퀀스(sequence) | 순서가 있는 값의 묶음. 리스트, 문자열, range |
| 한 바퀴 | 블록이 한 번 실행되는 것. 반복 변수 값 하나에 한 바퀴 |
range(시작, 끝, 간격) | 정수를 순서대로 만들어 주는 묶음. 끝 번호는 포함되지 않는다 |
첫 시도 — 1부터 10까지 더했는데 45
영수증 전에 몸풀기로 1부터 10까지의 합을 구합니다. 답은 55. 반복할 값이 정수라면 리스트를 손으로 쓰는 대신 range에 시킵니다.
total = 0
for n in range(1, 10):
total = total + n
print(total)📱 코드 실행(실습)은 태블릿·PC에서 이용할 수 있어요. 모바일에서는 위 코드를 눈으로 따라가며 확인하세요.
45
55가 아니라 45입니다. 10이 빠진 값. range(1, 10)이 만든 수를 눈으로 보면 이유가 드러납니다.
print(list(range(1, 10)))
print(list(range(5)))
print(list(range(1, 11)))
print(list(range(0, 10, 3)))
print(list(range(10, 0, -2)))📱 코드 실행(실습)은 태블릿·PC에서 이용할 수 있어요. 모바일에서는 위 코드를 눈으로 따라가며 확인하세요.
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[0, 3, 6, 9]
[10, 8, 6, 4, 2]
첫 줄이 9에서 끝납니다. range(1, 10)은 "1부터 10까지"가 아니라 **"1부터 시작해 10 앞에서 멈춘다"**입니다. 7편 슬라이싱의 cart[1:4]가 4번 칸을 빼고 세 칸만 주던 것과 같은 규칙입니다. 공식 문서의 표현을 빌리면 끝값은 만들어지는 수열에 포함되지 않고, range(10)은 길이 10인 리스트의 올바른 인덱스 열 개를 만듭니다. 0부터 9까지. 리스트 번호가 0에서 시작하니 끝을 빼야 개수가 딱 맞습니다.

range(1, 11)이 만드는 수는 1부터 10까지 열 개입니다. 끝에 적은 11은 들어오지 않습니다. 숫자 하나면 0부터, 셋이면 세 번째가 건너뛰는 간격입니다.
그러니 10까지 더하려면 끝에 11을 적습니다.
total = 0
for n in range(1, 11):
total += n
print(total)
print(n)📱 코드 실행(실습)은 태블릿·PC에서 이용할 수 있어요. 모바일에서는 위 코드를 눈으로 따라가며 확인하세요.
55
10
55입니다. total += n은 total = total + n을 줄여 쓴 것으로 5편 연산자에서 본 표기입니다. 마지막 줄의 print(n)은 반복이 끝난 뒤에 찍은 값인데 10이 나옵니다. 반복 변수는 블록이 끝나도 사라지지 않고 마지막 값을 그대로 갖고 있습니다. 나중에 같은 이름을 다른 뜻으로 쓰면 헷갈리는 자리라 알아 두는 편이 좋습니다.
range가 리스트를 미리 만들어 두는 것은 아닙니다. print(range(10))을 하면 [0, 1, …]이 아니라 range(0, 10)이라고만 나옵니다. 돌 때마다 다음 수를 하나씩 내주는 물건이라 백만까지 돌려도 백만 칸짜리 리스트가 생기지 않습니다. 그래서 위에서 눈으로 보려고 list(range(…))로 한 번 감쌌습니다.
리스트는 range 없이 그대로 돕니다
영수증으로 돌아옵니다. 값이 정수가 아니라 장바구니라면 range가 필요 없습니다. 리스트를 in 뒤에 그대로 놓으면 칸을 하나씩 꺼내 줍니다.
cart = ["사과", "우유", "계란", "빵", "커피"]
for item in cart:
print(item, len(item))
print("끝")📱 코드 실행(실습)은 태블릿·PC에서 이용할 수 있어요. 모바일에서는 위 코드를 눈으로 따라가며 확인하세요.
사과 2
우유 2
계란 2
빵 1
커피 2
끝
item에 사과, 우유, 계란, 빵, 커피가 차례로 담기고 블록이 다섯 번 돕니다. print("끝")은 들여쓰기가 없어 한 번. 가격 리스트도 같은 모양으로 돌면서 더하면 합계가 나옵니다.
prices = [3000, 2500, 6000, 4200, 8900]
total = 0
for p in prices:
total += p
print(p, "누적", total)
print("합계", total)📱 코드 실행(실습)은 태블릿·PC에서 이용할 수 있어요. 모바일에서는 위 코드를 눈으로 따라가며 확인하세요.
3000 누적 3000
2500 누적 5500
6000 누적 11500
4200 누적 15700
8900 누적 24600
합계 24600
total은 반복 밖에서 0으로 시작해야 합니다. 블록 안에 total = 0을 넣으면 매 바퀴 0으로 되돌아가 마지막 값 8,900만 남습니다. 초보 코드에서 자주 보는 실수라 그림으로 한 번 짚어 둡니다.

total은 반복 밖에서 0으로 시작해 한 바퀴마다 한 번씩 자랍니다. 진한 칸이 이번 바퀴에 더한 값입니다. 반복이 끝난 뒤 print(total)이 찍는 것은 마지막 막대의 24,600입니다.
이름과 가격을 나란히 — range(len(…))
영수증에는 물건 이름과 값이 한 줄에 같이 찍혀야 합니다. 리스트가 둘인데 for는 한 번에 하나만 돕니다. 이럴 때 range가 다시 나옵니다. 두 리스트의 칸 번호를 돌면 같은 번호로 양쪽을 꺼낼 수 있습니다.
cart = ["사과", "우유", "계란", "빵", "커피"]
prices = [3000, 2500, 6000, 4200, 8900]
for i in range(len(cart)):
print(i, cart[i], prices[i])📱 코드 실행(실습)은 태블릿·PC에서 이용할 수 있어요. 모바일에서는 위 코드를 눈으로 따라가며 확인하세요.
0 사과 3000
1 우유 2500
2 계란 6000
3 빵 4200
4 커피 8900
len(cart)가 5이니 range(5), 곧 0부터 4까지. 칸이 다섯이면 마지막 번호는 4라던 7편 규칙이 여기서 range의 끝 빠짐과 정확히 맞물립니다. 끝을 빼기 때문에 range(len(cart))는 언제나 리스트의 번호와 같은 범위가 됩니다. 이 궁합 덕에 range(len(리스트))는 파이썬 코드에서 관용구처럼 쓰입니다. 공식 문서는 번호와 값이 같이 필요할 때 enumerate가 더 편하다고 덧붙이는데, 그 함수는 다음 시즌에서 다룹니다.
세 번째 시도 — 돌면서 지웠더니 계란이 남았습니다
계산을 마친 물건을 장바구니에서 빼는 코드를 붙여 봅니다. 우유와 계란은 이미 샀다고 치고 지웁니다.
cart = ["사과", "우유", "계란", "빵", "커피"]
for item in cart:
if item == "우유" or item == "계란":
cart.remove(item)
print(cart)📱 코드 실행(실습)은 태블릿·PC에서 이용할 수 있어요. 모바일에서는 위 코드를 눈으로 따라가며 확인하세요.
['사과', '계란', '빵', '커피']
우유는 지워졌는데 계란이 남았습니다. 에러도 없습니다. for는 리스트를 칸 번호 순서로 읽습니다. 둘째 바퀴에 1번 칸 우유를 지우면 뒤에 있던 계란이 1번 칸으로 당겨 오는데, for는 다음 바퀴에 2번 칸을 봅니다. 그 자리에는 빵이 와 있습니다. 계란은 검사를 받지 못한 채 지나갑니다.
![위쪽 선반에 사과·우유·계란·빵·커피 다섯 칸이 있고 우유 칸이 노랗게 칠해져 두 번째 바퀴에 우유를 지운다고 적혀 있으며, 아래 선반은 사과·계란·빵·커피 네 칸으로 줄어 계란이 1번 칸으로 당겨졌지만 빵 칸이 노랗게 칠해져 for는 2번 칸으로 간다고 적혀 있고, 계란 칸에 빨간 점선 테두리와 검사도 못 받고 남는다는 메모가 있으며, 맨 아래 초록 상자에 cart[:] 사본을 돌기와 keep 새 리스트 만들기 두 가지 고치는 법이 적힌 그림](/uploads/python-for-remove.png)
돌고 있는 리스트를 지우면 뒤 칸이 앞으로 당겨지고, for는 다음 번호로 넘어갑니다. 당겨온 값은 검사를 건너뜁니다. 사본을 돌거나 새 리스트를 만들면 됩니다.
공식 문서는 이 상황을 두고 컬렉션을 돌면서 같은 컬렉션을 고치는 코드는 올바르게 만들기 어렵다고 적고, 사본을 돌거나 새 컬렉션을 만들라고 권합니다. 둘 다 7편에서 본 문법입니다.
cart = ["사과", "우유", "계란", "빵", "커피"]
for item in cart[:]:
if item == "우유" or item == "계란":
cart.remove(item)
print(cart)
cart = ["사과", "우유", "계란", "빵", "커피"]
keep = []
for item in cart:
if item != "우유" and item != "계란":
keep.append(item)
print(keep)📱 코드 실행(실습)은 태블릿·PC에서 이용할 수 있어요. 모바일에서는 위 코드를 눈으로 따라가며 확인하세요.
['사과', '빵', '커피']
['사과', '빵', '커피']
첫 방법은 cart[:]로 만든 복사본을 돌면서 원본을 지웁니다. 복사본은 줄어들지 않으니 다섯 바퀴가 온전히 돕니다. 둘째 방법은 남길 것만 새 리스트에 담습니다. 저는 둘째 쪽을 더 자주 씁니다. 지우는 코드보다 남기는 코드가 읽을 때 뜻이 분명해서입니다.
완성 — 영수증 열 줄
세 번의 시도를 합치면 처음에 보여 드린 영수증이 됩니다. 이름과 값을 같이 읽어야 하니 range(len(cart)), 합계는 반복 밖에서 0, 계산이 끝난 뒤 장바구니는 새 리스트로.
cart = ["사과", "우유", "계란", "빵", "커피"]
prices = [3000, 2500, 6000, 4200, 8900]
total = 0 # 반복 밖에서 시작
for i in range(len(cart)): # 0부터 4까지 — 끝 5는 빠집니다
total += prices[i] # 한 바퀴에 한 번
print(cart[i], prices[i], "누적", total)
print("합계", total)
paid = [] # 새 리스트에 담는 쪽
for item in cart:
if item != "우유":
paid.append(item)
print(paid)📱 코드 실행(실습)은 태블릿·PC에서 이용할 수 있어요. 모바일에서는 위 코드를 눈으로 따라가며 확인하세요.
사과 3000 누적 3000
우유 2500 누적 5500
계란 6000 누적 11500
빵 4200 누적 15700
커피 8900 누적 24600
합계 24600
['사과', '계란', '빵', '커피']
물건이 여섯 개가 되면 두 리스트에 한 칸씩만 붙이면 됩니다. 코드는 한 글자도 안 바뀝니다. 그것이 반복문을 쓰는 이유입니다.
조금 더 — 문자열도 돌고, 거꾸로도 돕니다
in 뒤에 올 수 있는 것은 리스트만이 아닙니다. 문자열을 놓으면 글자가 한 자씩 나옵니다. range의 세 번째 자리에 음수를 주면 거꾸로 셉니다.
for ch in "파이썬":
print(ch, end=" ")
print()
for n in range(10, 0, -2):
print(n, end=" ")
print()
print(sum(range(1, 11)))📱 코드 실행(실습)은 태블릿·PC에서 이용할 수 있어요. 모바일에서는 위 코드를 눈으로 따라가며 확인하세요.
파 이 썬
10 8 6 4 2
55
end=" "는 줄을 바꾸지 않고 한 칸 띄우라는 뜻으로, 2편 print에서 나온 옵션입니다. range(10, 0, -2)는 10에서 시작해 2씩 줄이며 0 앞에서 멈춥니다. 마지막 줄의 sum(range(1, 11))은 for 없이 합을 구한 것입니다. 이렇게 묶음을 통째로 받는 함수가 많아서, range가 리스트를 만들지 않고도 쓸모가 있습니다.
반복을 중간에 끊는 break와 한 바퀴만 건너뛰는 continue, 그리고 조건이 참인 동안 계속 도는 while은 다음 편에서 다룹니다. 무한 루프를 스스로 멈추는 법이 그 편의 주제입니다. 예제는 파이썬 3 기준이며 2026년 9월 8일 작성했습니다.
for 하나로 본 문법 아홉 개
cart = ["사과", "우유", "계란"], prices = [3000, 2500, 6000]일 때입니다.
| 문법 | 뜻 | 예 | 결과 |
|---|---|---|---|
for x in 묶음: | 묶음에서 하나씩 꺼내 x에 담고 블록 실행 | for item in cart: | 세 바퀴 |
| 들여쓴 블록 | 매 바퀴 실행되는 줄 | print(item) | 사과, 우유, 계란 |
range(끝) | 0부터 끝 앞까지 | range(3) | 0, 1, 2 |
range(시작, 끝) | 시작부터 끝 앞까지 | range(1, 4) | 1, 2, 3 |
range(시작, 끝, 간격) | 간격만큼 건너뛰며, 음수면 거꾸로 | range(6, 0, -2) | 6, 4, 2 |
range(len(리스트)) | 리스트의 칸 번호 전부 | range(len(cart)) | 0, 1, 2 |
total += x | 반복 밖에서 0으로 시작해 누적 | total += prices[i] | 11500 |
for ch in 문자열: | 글자 한 자씩 | for ch in "빵": | 빵 |
| 돌면서 원본 수정 | 칸이 당겨져 건너뜀. 사본(cart[:])이나 새 리스트로 | for item in cart[:]: | 다섯 바퀴 온전히 |
끝 번호를 바꾸면 출력은 어떻게 될까요
미니 퀴즈
참고 자료
정의와 동작은 파이썬 공식 문서를 기준으로 확인했습니다. 한국어 번역본입니다.
- 파이썬 자습서 4.2 for 문 — 시퀀스의 항목을 순서대로 이터레이션한다는 정의와, 돌면서 같은 컬렉션을 고치지 말고 사본이나 새 컬렉션을 쓰라는 권고: https://docs.python.org/ko/3/tutorial/controlflow.html#for-statements
- 파이썬 자습서 4.3 range() 함수 — 끝값은 포함되지 않는다는 규칙, 시작·간격 지정, range가 리스트가 아니라는 설명: https://docs.python.org/ko/3/tutorial/controlflow.html#the-range-function
- 파이썬 표준 라이브러리 "시퀀스 형 — list, tuple, range" — range 객체의 정의와 공통 연산: https://docs.python.org/ko/3/library/stdtypes.html#ranges
포켓코딩(PYTHON1) 8편 · 7편(파이썬 리스트)에서 이어집니다. 예제 코드는 강사 개인 GitHub 저장소의 연습 문제를 바탕으로 다시 썼습니다. 다음 편: 파이썬 while과 무한 루프 — 멈출 조건은 내가 만듭니다.