방송대 파이썬프로그래밍기초 6강: while·for 반복과 리스트 순회
같은 문장을 다섯 번 출력하려고 print()를 다섯 줄 복사하면 당장은 작동하지만 횟수가 바뀔 때마다 코드를 고쳐야 한다. 반복 구조는 되풀이할 명령을 한 번만 쓰고 조건이나 데이터 묶음으로 실행 횟수를 제어한다. 이 글은 while의 상태 변화와 종료 조건, for의 리스트 순회를 직접 추적하여 두 반복문을 선택하고 무한 반복과 인덱스 오류를 피하는 방법을 설명한다.
복사한 다섯 줄에서 바뀌는 것과 반복되는 것을 먼저 찾는다
“저는 파이썬을 잘 합니다.”를 다섯 번 출력하는 가장 단순한 방법은 같은 print() 문을 다섯 번 쓰는 것이다. 그러나 열 번 출력하려면 다섯 줄을 더 만들고, 문장을 바꾸려면 여러 줄을 함께 관리해야 한다. 같은 작업을 여러 번 수행한다는 의도가 코드의 구조에 드러나지 않는 것도 문제다.
반복 구조는 특정 영역의 명령문을 여러 번 재실행하는 구조다. 동일한 코드를 반복해서 작성하지 않아도 지정된 작업을 수행할 수 있으며, 반복 횟수나 계속 여부는 조건으로 제어한다. Python에서는 대표적으로 while과 for를 사용한다.
반복 설계의 출발점: 되풀이할 명령 블록, 반복을 제어할 값이나 데이터 묶음, 계속할 조건, 다음 반복으로 상태를 바꾸는 명령을 분리한다.
while은 실행 전에 조건을 검사하는 조건 제어 반복이다
while은 반복을 계속할 조건이 참인 동안 들여쓰기 된 명령 블록을 실행한다. 실행 순서는 조건 검사 → 명령 블록 실행 → 상태 변화 → 다시 조건 검사로 이어진다. 조건이 처음부터 거짓이면 명령 블록은 한 번도 실행되지 않는다.
msg = "저는 파이썬을 잘 합니다."
count = 1
while count <= 5:
print(msg)
count = count + 1
count는 지금 몇 번째 반복인지 나타내고, count <= 5는 1부터 5까지 실행하도록 경계를 정한다. 출력 뒤 count를 1 늘리기 때문에 언젠가 6이 되어 조건이 거짓으로 바뀐다. 반복문은 몸체만 읽지 말고 조건을 바꾸는 명령까지 함께 읽어야 한다.
| 조건 검사 시점 | count <= 5 | 수행 결과 | 증가 뒤 값 |
|---|---|---|---|
| 1회 | 1 <= 5, 참 | 문장 출력 | 2 |
| 2회 | 2 <= 5, 참 | 문장 출력 | 3 |
| 3회 | 3 <= 5, 참 | 문장 출력 | 4 |
| 4회 | 4 <= 5, 참 | 문장 출력 | 5 |
| 5회 | 5 <= 5, 참 | 문장 출력 | 6 |
| 6회 검사 | 6 <= 5, 거짓 | 몸체를 실행하지 않고 종료 | - |
증감 할당은 읽기·계산·저장의 세 동작을 한 문장에 묶는다
count = count + 1은 수학의 등식이 아니라 할당문이다. 먼저 메모리에서 count의 현재 값을 읽고, 그 값에 1을 더한 뒤, 결과를 다시 같은 변수에 저장한다. 그래서 왼쪽과 오른쪽에 같은 이름이 있어도 모순이 아니다.
count += 1은 같은 동작을 간결하게 표현한 증감 할당이다. 일반 연산자와 할당 연산자를 결합한 복합 할당 연산자에는 +=, -=, *=, /=, %=, **=, //= 등이 있다.
| 복합 할당 | 풀어 쓴 형태 | 의미 |
|---|---|---|
a += b | a = a + b | 현재 a에 b를 더해 다시 저장한다 |
a -= b | a = a - b | 현재 a에서 b를 뺀다 |
a *= b | a = a * b | 현재 a에 b를 곱한다 |
a //= b | a = a // b | 몫을 계산해 다시 저장한다 |
무한 반복은 조건이 참이어서가 아니라 거짓이 될 경로가 없어서 생긴다
다음 코드는 겉으로는 다섯 번 출력할 것처럼 보이지만 count가 1에서 바뀌지 않는다. 조건 count <= 5는 계속 참이고 반복은 끝나지 않는다.
msg = "저는 파이썬을 잘 합니다."
count = 1
while count <= 5:
print(msg)
# count의 값이 바뀌지 않으므로 종료할 수 없다.
무한 반복을 진단할 때 조건식만 보며 “현재 참이다”라고 말하는 것으로는 부족하다. 반복 전의 초기값이 무엇인지, 몸체에서 조건에 쓰인 변수가 어떻게 바뀌는지, 그 변화가 언젠가 조건을 거짓으로 만드는지를 확인해야 한다. 이 예에서는 몸체 끝에 count += 1을 넣어 종료 경로를 만든다.
경계 점검: count = 0이고 조건이 count < 5이면 0·1·2·3·4에서 다섯 번 실행한다. 시작값이나 비교 연산자 하나가 바뀌면 실행 횟수도 달라지므로 초기값·경계·증가량을 한 묶음으로 계산한다.
합계 반복은 초기화·누적·증가·종료의 네 장치로 설계한다
1부터 사용자가 입력한 n까지의 합을 구하는 문제를 단계별로 설계해 보자. 먼저 반복될 핵심 계산은 현재 합에 i를 더하는 total += i다. 그다음 이 명령을 반복 구조로 감싸고, i가 n 이하인 동안 계속하도록 조건을 정한다. 마지막으로 i += 1을 넣어 다음 수로 이동한다.
total = 0
i = 1
n = 5
while i <= n:
total += i
i += 1
print(total)
| 장치 | 코드 | 필요한 이유 |
|---|---|---|
| 초기화 | total = 0, i = 1 | 합계와 첫 항의 출발 상태를 정한다 |
| 누적 | total += i | 이번 항을 이전까지의 합에 더한다 |
| 증가 | i += 1 | 다음 항으로 이동하여 같은 값의 반복을 막는다 |
| 종료 | i <= n | n까지 포함하고 n + 1에서 멈춘다 |
실행 중 total은 0 → 1 → 3 → 6 → 10 → 15로 변한다. i는 6이 된 뒤 조건을 다시 검사하고 종료한다. total = 0을 반복문 안에 넣으면 매번 합계를 0으로 되돌리므로 누적이 깨지고, 증가식을 누적보다 앞에 두면 1을 빠뜨리고 6을 더하는 경계 오류가 생긴다.
구구단은 반복되는 계산식과 변하는 피연산자를 분리한다
사용자가 9단을 요청하면 반복되는 것은 “9와 현재 순서를 곱해 출력한다”는 명령이고, 변하는 것은 1부터 9까지의 곱하는 수다. while로 작성한다면 곱하는 수를 1로 초기화하고 9 이하인지 검사한 뒤 출력과 증가를 반복한다.
dan = 9
i = 1
while i <= 9:
print(dan, "X", i, "=", dan * i)
i += 1
첫 출력은 9 X 1 = 9, 마지막 출력은 9 X 9 = 81이다. i < 9로 조건을 바꾸면 8까지만 실행되어 마지막 항이 빠진다. 출력 형식보다 반복 경계가 결과 집합을 어떻게 바꾸는지 확인하는 것이 중요하다.
while과 for는 반복 횟수보다 제어 근거로 고른다
while은 조건이 참인 동안 계속하는 조건 제어 반복이고, for는 시퀀스의 원소를 하나씩 변수에 할당하는 계수 제어 반복이다. 둘 다 여러 번 실행하지만 반복을 계속할 근거가 다르다.
| 판단 기준 | while | for |
|---|---|---|
| 계속하는 근거 | 불리언 조건이 참인가? | 시퀀스에 아직 처리할 원소가 남았는가? |
| 상태 변화 | 몸체에서 조건 관련 변수를 직접 바꾸는 경우가 많다 | 반복할 때마다 다음 원소가 변수에 순서대로 할당된다 |
| 적합한 문제 | 종료 시점이 상태나 입력 조건으로 결정되는 반복 | 리스트 등 정해진 데이터 묶음의 모든 원소 처리 |
| 대표 위험 | 상태 변화 누락으로 무한 반복이 생긴다 | 원소 값과 인덱스를 혼동하거나 일부만 처리한다 |
반복 횟수를 미리 안다는 사실만으로 항상 for를 써야 하는 것은 아니고, 모른다고 항상 while인 것도 아니다. 이 차시의 핵심 판단은 조건의 변화를 직접 관리할지, 이미 준비된 시퀀스의 원소를 차례로 받을지다.
리스트는 여러 값을 순서와 인덱스로 묶는 변경 가능한 시퀀스다
리스트는 여러 데이터 값을 순서대로 묶어 저장하는 자료구조다. 원소(element)의 나열을 저장하는 시퀀스 타입이며, 저장 순서가 유지된다. 각 원소에는 0부터 시작하는 고유한 순번인 인덱스가 부여된다.
리스트는 대괄호 [] 안에 원소를 쉼표로 구분해 만들 수 있다. 개별 원소의 값을 바꾸거나 원소를 추가·삭제할 수 있고, 숫자·문자열처럼 서로 다른 타입의 값을 함께 담거나 리스트 안에 다른 리스트를 둘 수도 있다.
heights = [1, 5, 14, 26, 31]
profile = [181.78, "dark brown", "black"]
heights는 같은 종류의 높이를 순서대로 저장하고, profile은 실수와 문자열을 함께 담는다. 리스트 변수는 개별 값을 직접 하나만 보관하는 일반 변수와 달리 여러 원소가 모인 목록을 참조해 접근하도록 한다.
인덱스는 위치 번호이며 첫 원소의 번호는 0이다
인덱스 연산자 []를 사용하면 시퀀스의 특정 원소에 접근할 수 있다. heights = [1, 5, 14, 26, 31]에서 heights[0]은 1, heights[2]는 14, heights[4]는 31이다.
heights[4] = 45를 실행하면 마지막 원소가 31에서 45로 바뀐다. 원소가 다섯 개이므로 유효한 인덱스는 0·1·2·3·4다. 사람의 “첫 번째”를 인덱스 1로 착각하면 실제로는 두 번째 원소에 접근하고, heights[5]는 여섯 번째 위치를 요구하므로 범위를 벗어난다.
인덱스 검산: 길이가 n인 리스트의 첫 인덱스는 0이고 마지막 인덱스는 n - 1이다. 원소 개수와 마지막 번호를 같은 값으로 두지 않는다.
for는 리스트에서 값을 꺼내 반복 변수에 차례로 맡긴다
for 반복변수 in 시퀀스: 형식은 리스트의 원소를 처음부터 하나씩 반복 변수에 할당하고 명령 블록을 실행한다. 다음 예에서 height는 인덱스가 아니라 실제 원소값 1, 5, 14, 26, 31을 차례로 받는다.
heights = [1, 5, 14, 26, 31]
for height in heights:
print(height)
출력은 리스트의 저장 순서와 같은 다섯 줄이다. while로 같은 일을 하려면 인덱스 초기화, 범위 조건, 인덱스 증가를 직접 관리해야 하지만, for는 “각 원소를 한 번씩 처리한다”는 의도를 코드에 바로 드러낸다.
리스트와 for를 결합하면 입력 집합과 계산 규칙을 분리할 수 있다
강의자료의 원뿔 문제는 반지름 10과 높이 1·5·14·26·31에 대해 부피와 겉넓이를 각각 계산한다. 높이를 하나씩 다시 입력하거나 계산 코드를 복사하지 않고 리스트에 묶은 뒤 같은 공식을 순회 적용할 수 있다.
radius = 10
heights = [1, 5, 14, 26, 31]
for height in heights:
slant = pow(radius ** 2 + height ** 2, 0.5)
volume = 1 / 3 * 3.14 * radius ** 2 * height
surface = 3.14 * radius ** 2 + 3.14 * radius * slant
print(height, volume, surface)
첫 반복에서는 height가 1이므로 부피는 약 104.67, 겉넓이는 약 629.56이다. 마지막 반복에서는 높이 31을 사용해 부피가 약 3244.67, 겉넓이가 약 1336.79가 된다. 높이 목록을 바꾸어도 계산식은 수정할 필요가 없다.
이 구조의 장점은 리스트가 처리할 데이터 집합을, for 몸체가 각 데이터에 적용할 규칙을 맡는다는 점이다. 목록에 높이 하나를 추가하면 같은 계산이 자연스럽게 한 번 더 실행된다.
반복 오류는 시작·경계·변화·대상·접근 순서로 좁힌다
반복 코드가 예상한 횟수와 다른 결과를 낼 때 문법만 고치지 말고 제어 구조를 추적해야 한다. 다음 다섯 질문은 while과 for, 리스트 문제를 함께 진단한다.
| 점검 순서 | 질문 | 대표 오류 |
|---|---|---|
| 1. 시작 | 누적값과 반복 변수를 올바르게 초기화했는가? | 합계를 반복문 안에서 0으로 되돌린다 |
| 2. 경계 | 마지막 값을 포함할지에 맞게 <와 <=를 골랐는가? | 구구단의 9번째 항이 빠진다 |
| 3. 변화 | while 조건을 거짓으로 만들 상태 변화가 있는가? | 증가식 누락으로 무한 반복한다 |
| 4. 대상 | for가 순회해야 할 시퀀스와 원소 순서가 맞는가? | 일부 값만 별도로 처리해 목록 변경을 놓친다 |
| 5. 접근 | 인덱스가 0부터 길이 - 1 범위 안에 있는가? | 첫 원소를 1번으로 착각하거나 범위를 벗어난다 |
핵심 개념 정리
- 반복 구조는 동일한 명령을 복사하지 않고 조건이나 시퀀스에 따라 여러 번 실행한다.
while은 조건을 먼저 검사하며 초기 상태, 계속 조건, 몸체, 상태 변화가 함께 종료 경로를 만든다.- 복합 할당
a += b는 현재 값을 읽어 계산한 뒤 같은 변수에 다시 저장하는a = a + b와 같다. - 누적 반복은 초기화·누적·증가·종료 조건을 분리해 설계하고 변수의 상태 변화를 추적한다.
for는 시퀀스의 원소를 반복 변수에 순서대로 할당하므로 데이터 묶음 전체를 처리할 때 적합하다.- 리스트는 여러 원소를 순서대로 저장하는 변경 가능한 시퀀스이며, 서로 다른 데이터 타입과 중첩 리스트도 담을 수 있다.
- 리스트의 인덱스는 0부터 시작하므로 길이가
n일 때 마지막 인덱스는n - 1이다. - 리스트는 처리할 데이터 집합을, 반복문 몸체는 각 원소에 적용할 규칙을 분리한다.
반복문을 작성하기 전에 무엇을 되풀이할지와 무엇이 매번 달라질지를 먼저 적는다. 조건의 변화를 직접 관리하면 while, 준비된 시퀀스의 각 원소를 처리하면 for가 자연스럽다. while에서는 초기값·경계·증가량으로 종료를 증명하고, for와 리스트에서는 원소값과 0부터 시작하는 인덱스를 구분한다. 마지막으로 변수 변화표를 한 줄씩 작성하면 실행 횟수, 누적값과 경계 오류를 코드 실행 전에도 검산할 수 있다.
예상문제 10선
1. 반복 구조의 목적을 가장 정확하게 설명한 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ④
- ① 오답: 반복 제어에서는 조건을 바꾸기 위해 변수의 상태를 갱신하는 경우가 많다.
- ② 오답: 리스트 순회는 일반적으로 준비된 여러 원소를 차례로 처리한다.
- ③ 오답: 중복 코드를 줄이고 실행 규칙을 명확히 하는 것이 반복 구조의 장점이다.
- ④ 정답: 반복 대상과 제어 조건을 분리하여 같은 작업을 재사용하는 구조를 설명한다.
2. while과 for를 구분하는 설명으로 옳은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ②
- ① 오답: 두 반복문의 제어 방식을 서로 뒤바꾸었다.
- ② 정답: 조건 변화의 직접 관리와 시퀀스 원소의 순차 할당이라는 차이를 정확히 짚는다.
- ③ 오답: 실행 횟수는 조건과 시퀀스 길이에 따라 달라진다.
- ④ 오답: 두 문법은 반복을 계속할 근거와 변수 변화 방식이 다르다.
3. count = 1이고 while count <= 3 몸체 끝에서 count += 1을 실행한다. 몸체 실행 횟수는?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ①
- ① 정답:
count가 1·2·3일 때 실행하고 4에서 조건이 거짓이 된다. - ② 오답:
<=는 경계값 3을 포함하므로 세 번째 실행이 있다. - ③ 오답: 4에서는 조건 검사만 하고 몸체는 실행하지 않는다.
- ④ 오답: 증가식이 조건 변수를 바꾸므로 4에 도달해 종료된다.
4. a = 10인 상태에서 a //= 3을 실행한 뒤 a의 값은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ③
- ① 오답: 10을 3으로 나눈 나머지는 1이지만
//는 몫을 구한다. - ② 오답: 실수 나눗셈
/의 결과에 가깝고 몫 연산//의 결과가 아니다. - ③ 정답:
a //= 3은a = a // 3이므로 10을 3으로 나눈 몫 3을 저장한다. - ④ 오답: 곱셈 복합 할당
*=로 해석했을 때 나오는 값이다.
5. 다음 반복이 끝나지 않는 직접적인 원인은 무엇인가? count = 1; while count <= 5: print(count)
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ③
- ① 오답: 정수 카운터는 반복 횟수를 제어하는 일반적인 방법이며 종료 실패의 원인이 아니다.
- ② 오답: 출력문은 반복할 작업이고 그 자체가 조건을 계속 참으로 만들지는 않는다.
- ③ 정답:
count가 1로 고정되어 조건이 거짓이 될 경로가 없다. - ④ 오답: 등호는 5를 포함하게 할 뿐 증가식이 있으면 6에서 정상 종료한다.
6. 본문의 합산 코드에서 n = 5일 때 total의 최종값은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ①
- ① 정답: 상태는
0 → 1 → 3 → 6 → 10 → 15로 변해 1부터 5까지 모두 누적된다. - ② 오답: 1부터 4까지만 합한 값으로 경계값 5를 빠뜨렸다.
- ③ 오답: 반복 횟수나 마지막 항을 합계와 혼동한 값이다.
- ④ 오답: 조건이 거짓이 되는 6은 합계에 포함되지 않는다.
7. Python 리스트의 설명으로 옳은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ④
- ① 오답: 리스트는 여러 원소의 순서를 유지하는 시퀀스다.
- ② 오답: 첫 인덱스는 0이고 리스트의 개별 원소를 수정할 수 있다.
- ③ 오답: Python 리스트는 서로 다른 타입의 값도 함께 담을 수 있다.
- ④ 정답: 순서, 인덱스 접근, 변경 가능성이라는 리스트의 핵심 성질을 모두 담는다.
8. values = [3, 6, 9, 12]에서 values[2]의 값은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ②
- ① 오답: 6은 인덱스 1에 있으며 인덱스를 사람의 순서 번호와 혼동했다.
- ② 정답: 인덱스는 0부터 시작하므로 0→3, 1→6, 2→9로 대응한다.
- ③ 오답: 12는 네 번째 원소지만 인덱스는 3이다.
- ④ 오답: 길이가 4인 리스트의 유효 인덱스는 0부터 3이므로 2는 범위 안이다.
9. 다음 코드의 출력 순서는? for x in [2, 4, 6]: print(x)
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ④
- ① 오답:
x는 인덱스가 아니라 리스트의 실제 원소값을 받는다. - ② 오답: 기본 순회는 리스트에 저장된 순서를 뒤집지 않는다.
- ③ 오답: 첫 원소 처리 후 다음 원소가 남아 있으므로 반복이 계속된다.
- ④ 정답:
x에 2·4·6이 순서대로 할당되어 각 값이 한 번씩 출력된다.
10. 높이 목록의 모든 값에 같은 원뿔 계산식을 적용하는 설계로 가장 적절한 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ③
- ① 오답: 데이터가 추가될 때 코드도 복제해야 하므로 입력 집합과 계산 규칙이 분리되지 않는다.
- ② 오답: 리스트를 만들었지만 나머지 원소를 처리하지 않아 반복 목적을 달성하지 못한다.
- ③ 정답: 처리할 값은 리스트에, 재사용할 공식은 반복문 몸체에 두어 모든 높이에 적용한다.
- ④ 오답: 상태 변화와 데이터 이동이 없어 같은 값만 계산하며 종료 경로도 없다.
참고 자료와 작성 기준
이 글은 해당 차시 강의자료를 바탕으로 학습 목적에 맞게 재구성한 비공식 학습자료입니다. while 실행 추적표, 초기값·경계·증가량의 오류 분석, 1부터 5까지 합의 상태 변화, 리스트 인덱스 검산과 원뿔 높이 순회 예제는 학습자가 반복 제어를 직접 재현하도록 새로 구성했습니다.
- 작성·편집: 올에이클래스 학습연구팀
- 주요 근거: 한국방송통신대학교 컴퓨터과학과, 「파이썬프로그래밍기초」 6강 반복 구조 강의자료, 2026
- 보충 자료: 외부 자료를 사용하지 않음
- 편집 원칙: 올에이클래스 편집 정책
- 최종 내용 검토: 2026-09-07
댓글
댓글 쓰기