Python & AI Tutorials Logo
Python 프로그래밍

12. for 반복문과 range()로 반복하기

11장에서는 조건이 참인 동안 동작을 반복하는 while 반복문(loop)을 배웠습니다. while 반복문은 강력하고 유연하지만, 반복 카운터를 수동으로 관리하고 조건을 갱신해야 합니다. Python은 또 다른 종류의 반복문(loop)인 for 반복문을 제공하는데, 이는 다른(하지만 매우 흔한) 작업—데이터 컬렉션(collection)의 각 항목을 한 번에 하나씩 처리하는 작업—에 특히 뛰어납니다.

for 반복문은 Python에서 가장 자주 사용되는 기능 중 하나입니다. 파일의 줄을 처리하든, 숫자 시퀀스(sequence)에서 통계를 계산하든, 문자열(string)의 각 문자를 확인하든, for 반복문은 데이터 시퀀스를 깔끔하고 읽기 쉬운 방식으로 처리할 수 있게 해줍니다. 이 장에서는 for 반복문이 어떻게 동작하는지, 카운팅 작업에 Python의 range() 함수를 어떻게 사용하는지, 그리고 break, continue, 그리고 덜 알려진 else 절(clause)로 반복 실행을 어떻게 제어하는지 살펴보겠습니다.

12.1) for 반복문과 반복(iteration) 개념

12.1.1) for 반복문이란?

Python의 for 반복문은 시퀀스(sequence)의 각 항목마다 코드 블록을 한 번씩 반복 실행합니다. 시퀀스는 문자열(string), 리스트(list)(14장에서 자세히 배울 것입니다), 또는 기타 다른 항목들의 컬렉션(collection)일 수 있습니다. while 반복문과의 핵심 차이는 for 반복문이 반복(iteration)을 자동으로 처리한다는 점입니다. 카운터를 수동으로 업데이트하거나 조건을 확인할 필요가 없습니다.

다음은 for 반복문의 기본 구조입니다:

python
for variable in sequence:
    # 각 항목에 대해 실행할 코드 블록
    # variable에는 현재 항목이 들어 있습니다

for 반복문은 다음과 같이 동작합니다:

  1. Python이 시퀀스에서 첫 번째 항목을 가져와 변수에 할당합니다
  2. 코드 블록(for 문 아래로 들여쓰기된 부분)이 실행됩니다
  3. Python이 다음 항목을 가져와 변수에 할당하고 블록을 다시 실행합니다
  4. 시퀀스의 모든 항목이 처리될 때까지 계속됩니다

문자열로 간단한 예를 보겠습니다:

python
# 이름의 각 문자를 출력하기
name = "Alice"
for character in name:
    print(character)

Output:

A
l
i
c
e

이 예에서 문자열 "Alice"가 시퀀스입니다. 반복문은 각 문자를 한 번에 하나씩 처리합니다. 첫 번째 반복에서는 character'A'가 들어 있고, 두 번째 반복에서는 'l'이 들어 있는 식으로 진행됩니다. 변수 이름 character는 우리가 선택한 것입니다—letter, char, 또는 그냥 c라고 불러도 됩니다. 코드의 목적이 명확해지도록 이름을 선택하세요.

반복 변수(loop variable) 이름 짓기 관례: for 반복문을 작성할 때는 각 항목이 무엇을 나타내는지 설명하는 변수 이름을 선택하세요. 코드 이해에 값이 중요하다면 character, student, score처럼 설명적인 이름을 쓰세요. 단순히 반복 횟수를 세는 숫자 카운터라면 i를 사용합니다(그저 반복을 세기만 할 때). 값이 전혀 필요 없을 때는 _(언더스코어)를 사용하세요—이는 “이 값은 신경 쓰지 않습니다”라는 Python 관례입니다.

다음은 단어에서 모음을 세는 실용적인 예입니다:

python
# 단어에서 모음 개수 세기
word = "Python"
vowel_count = 0
 
for letter in word:
    if letter in "aeiouAEIOU":
        vowel_count += 1
        print(f"Found vowel: {letter}")
 
print(f"Total vowels: {vowel_count}")

Output:

Found vowel: o
Total vowels: 1

이 반복문은 "Python"의 각 글자를 검사합니다. 모음을 찾으면(7장에서 배운 in 연산자를 사용합니다) 카운터를 증가시키고 메시지를 출력합니다. 이 패턴—반복문 전에 카운터를 초기화하고, 반복문 안에서 업데이트하는 방식—은 프로그래밍에서 매우 흔합니다.

다음은 결과를 쌓아(accumulation) 만들어 가는 예입니다:

python
# 문자열에서 대문자 개수 세기
text = "Python Programming"
uppercase_count = 0
 
for char in text:
    if char.isupper():
        uppercase_count += 1
 
print(f"Found {uppercase_count} uppercase letters in '{text}'")

Output:

Found 2 uppercase letters in 'Python Programming'

이 예는 누적(accumulation) 패턴을 보여줍니다. 반복문 전에 카운터를 0으로 초기화한 다음, 각 문자를 검사하면서 대문자를 찾으면 카운터를 증가시킵니다. 반복문이 끝난 뒤에는 누적된 결과를 사용합니다. 이 패턴은 프로그래밍 전반에서 끊임없이 등장합니다—특정 기준을 만족하는 항목 개수 세기, 값 합산하기, 또는 결과를 한 조각씩 만들어 가기 같은 작업에서요.

12.1.2) 반복(iteration) 이해하기

반복(iteration)은 컬렉션(collection)의 각 요소(element)에 대해 어떤 동작을 반복하는 과정입니다. 어떤 객체(object)가 이터러블(iterable)이라고 말할 때는, Python이 for 반복문에서 그 요소를 한 번에 하나씩 처리할 수 있다는 뜻입니다. 문자열은 이터러블입니다—문자들을 순회할 수 있습니다. 곧 보겠지만, 다른 많은 Python 타입도 이터러블입니다.

for 반복문의 변수(예시의 characterletter)는 반복 변수(loop variable)라고 부릅니다. 이 변수는 for 반복문에 의해 자동으로 만들어지며 반복문의 스코프(scope) 안에서만 존재합니다. 반복을 한 번 돌 때마다 Python은 시퀀스에서 다음 항목을 이 변수에 할당합니다.

다음은 반복 변수가 어떻게 바뀌는지 보여주는 예입니다:

python
# 반복 변수가 어떻게 업데이트되는지 보여주기
colors = "RGB"  # Red, Green, Blue
for color_code in colors:
    print(f"Processing color code: {color_code}")
    print(f"  This is iteration for '{color_code}'")

Output:

Processing color code: R
  This is iteration for 'R'
Processing color code: G
  This is iteration for 'G'
Processing color code: B
  This is iteration for 'B'

반복을 한 번 돌 때마다 color_code는 문자열에서 서로 다른 문자를 담습니다. 반복문은 자동으로 다음 문자로 이동합니다—시퀀스를 진행시키기 위한 코드를 따로 작성할 필요가 없습니다.

12.1.3) 반복(iteration)에서 for 반복문 vs while 반복문

같은 문자 단위 처리를 while 반복문으로도 할 수 있지만, 더 많은 코드와 수동 관리가 필요합니다:

python
# while 반복문으로 문자열을 순회하기(더 복잡함)
name = "Alice"
index = 0
while index < len(name):
    character = name[index]
    print(character)
    index += 1  # 인덱스를 수동으로 업데이트해야 함

이는 앞서 본 for 반복문 예제와 같은 출력을 만들지만, 우리가 해야 했던 일을 보면 다음과 같습니다:

  • 인덱스 변수를 만들고 초기화하기
  • 각 반복마다 조건 index < len(name) 확인하기
  • name[index]로 문자를 수동으로 추출하기
  • 인덱스를 증가시키는 것을 기억하기(이를 잊으면 무한 반복문이 됩니다!)

for 반복문은 이 모든 것을 자동으로 처리합니다:

python
# for 반복문으로 문자열을 순회하기(더 간단함)
name = "Alice"
for character in name:
    print(character)

이쪽이 훨씬 깔끔하고 실수하기도 어렵습니다. 컬렉션(collection)의 각 항목을 처리하고 싶을 때 for 반복문이 자연스러운 선택입니다. 반복 로직을 더 세밀하게 제어해야 하거나, 미리 몇 번 반복해야 할지 모를 때는 while 반복문을 사용하세요.

아니오

for 반복문 시작

시퀀스에서 다음 항목 가져오기

더 많은 항목이 있는가?

항목을 반복 변수에 할당

반복문 본문 실행

반복문 종료

12.2) range()로 카운팅 반복문 사용하기

12.2.1) range() 함수 소개

for 반복문은 기존 시퀀스를 처리하는 데 뛰어나지만, 종종 특정 횟수만큼 동작을 반복해야 합니다—예를 들어 메시지를 다섯 번 출력하거나 처음 10개의 제곱수를 계산하는 경우처럼요. Python의 range() 함수는 for 반복문으로 순회할 수 있는 숫자 시퀀스를 생성합니다.

range()의 가장 단순한 형태는 인자 하나를 받는데, 0부터 시작하는 정수들을 그 개수만큼 생성합니다:

python
# 0부터 4까지 숫자 출력하기
for number in range(5):
    print(number)

Output:

0
1
2
3
4

⚠️ 흔한 실수: 초보자들은 range(5)가 1, 2, 3, 4, 5를 만든다고 기대하는 경우가 많지만, 실제로는 0, 1, 2, 3, 4를 만듭니다. 기억하세요: range(n)은 0에서 시작하고 n 직전에서 멈춥니다. 이 “직전에서 멈춤” 동작은 5장에서 배운 Python의 슬라이싱(slicing)과 일관됩니다. 범위는(기본값으로) 0에서 시작하고, stop 값은 포함하지 않고 그 직전까지 갑니다.

이 패턴은 특정 횟수만큼 동작을 반복하기에 완벽합니다:

python
# 인사말을 다섯 번 출력하기
for i in range(5):
    print(f"Welcome! (iteration {i})")

Output:

Welcome! (iteration 0)
Welcome! (iteration 1)
Welcome! (iteration 2)
Welcome! (iteration 3)
Welcome! (iteration 4)

변수 i는 반복 카운터의 흔한 이름입니다(“index” 또는 “iteration”의 약자). 물론 어떤 유효한 변수 이름이든 사용할 수 있습니다. 반복 변수의 값이 로직에 중요하지 않을 때 i는 관례적으로 많이 쓰입니다.

12.2.2) 시작값과 종료값 지정하기

range()에 인자를 두 개 전달하면 시작 위치와 종료 위치를 모두 지정할 수 있습니다:

python
# 1부터 5까지 숫자 출력하기
for number in range(1, 6):
    print(number)

Output:

1
2
3
4
5

여기서 range(1, 6)은 1에서 시작해 6 직전에서 멈추므로 1부터 5까지의 숫자를 제공합니다. 0이 아닌 값에서 카운팅을 시작해야 할 때 유용합니다.

이를 사용해 간단한 구구단을 계산해 보겠습니다:

python
# 7단을 1부터 10까지 출력하기
multiplier = 7
for number in range(1, 11):
    result = multiplier * number
    print(f"{multiplier} × {number} = {result}")

Output:

7 × 1 = 7
7 × 2 = 14
7 × 3 = 21
7 × 4 = 28
7 × 5 = 35
7 × 6 = 42
7 × 7 = 49
7 × 8 = 56
7 × 9 = 63
7 × 10 = 70

반복문은 1부터 10까지 실행되며, 각 숫자에 7을 곱합니다. 이는 range()가 특정 숫자 시퀀스에 대해 계산을 수행하기 쉽도록 해준다는 점을 보여줍니다.

12.2.3) step 값 사용하기

range() 함수는 세 번째 선택적 인자로 step 값을 받는데, 숫자 사이에서 얼마나 증가(또는 감소)할지를 결정합니다:

python
# 0부터 10까지 짝수 출력하기
for number in range(0, 11, 2):
    print(number)

Output:

0
2
4
6
8
10

range(0, 11, 2)에서는 0에서 시작해 11 직전에서 멈추며, 매번 2씩 증가합니다. 따라서 0부터 10까지의 모든 짝수를 얻습니다.

음수 step을 사용해 거꾸로 세는 것도 가능합니다:

python
# 10부터 1까지 카운트다운하기
for number in range(10, 0, -1):
    print(number)
print("Liftoff!")

Output:

10
9
8
7
6
5
4
3
2
1
Liftoff!

여기서 range(10, 0, -1)은 10에서 시작해 0 직전에서 멈추며, 매번 1씩 감소합니다. 음수 step이 범위를 역방향으로 세게 만듭니다.

1부터 100까지의 모든 홀수 합을 계산하는 실용적인 예를 보겠습니다:

python
# 1부터 100까지 모든 홀수 합산하기
total = 0
for number in range(1, 101, 2):  # 1에서 시작, 2씩 증가
    total += number
 
print(f"Sum of odd numbers from 1 to 100: {total}")

Output:

Sum of odd numbers from 1 to 100: 2500

range(1, 101, 2)를 사용하면 홀수(1, 3, 5, ..., 99)만 생성되므로, 반복문 안에서 각 숫자의 홀짝을 검사할 필요가 없습니다. 이는 코드를 더 효율적으로 만들고 의도도 더 명확하게 합니다.

12.2.4) range()가 실제로 반환하는 것

range() 함수는 메모리에 숫자 리스트를 만드는 것이 아니라, 필요할 때 숫자를 생성하는 range 객체(object)를 만듭니다. 이는 특히 큰 범위에서 메모리 효율적입니다:

python
# range()는 리스트가 아니라 range 객체를 반환합니다
numbers = range(1000000)
print(type(numbers))  # Output: <class 'range'>
print(numbers)        # Output: range(0, 1000000)

Output:

<class 'range'>
range(0, 1000000)

이 범위가 백만 개의 숫자를 나타내더라도, Python은 실제로 백만 개의 숫자를 모두 만들지 않기 때문에 메모리를 거의 사용하지 않습니다. 각 숫자는 반복문에서 필요할 때만 생성됩니다.

실제 숫자 리스트가 필요하다면 range를 변환할 수 있습니다:

python
# range를 리스트로 변환하기
small_numbers = list(range(5))
print(small_numbers)  # Output: [0, 1, 2, 3, 4]

Output:

[0, 1, 2, 3, 4]

리스트와 list() 함수는 14장에서 더 자세히 배울 것입니다. 지금은 range()가 변환 없이도 for 반복문과 완벽히 작동한다는 점만 알아두세요.

12.3) 문자열과 기타 시퀀스 순회하기

12.3.1) 문자열을 문자 단위로 순회하기

이미 문자열을 순회하는 여러 예를 보았습니다. 문자열은 문자 시퀀스이기 때문에, 각 문자를 개별적으로 검사하거나 처리해야 하는 경우가 많아 for 반복문의 가장 흔한 사용처 중 하나입니다.

다음은 비밀번호에 숫자가 최소 하나 포함되어 있는지 확인하는 예입니다:

python
# 비밀번호에 숫자가 최소 하나 포함되어 있는지 확인하기
password = "secure123"
has_digit = False
 
for character in password:
    if character.isdigit():
        has_digit = True
        print(f"Found digit: {character}")
 
if has_digit:
    print("Password contains at least one digit ✓")
else:
    print("Password must contain at least one digit ✗")

Output:

Found digit: 1
Found digit: 2
Found digit: 3
Password contains at least one digit ✓

반복문은 .isdigit() 문자열 메서드(5장에서 배웠습니다)를 사용해 각 문자를 검사합니다. 숫자를 찾으면 has_digitTrue로 설정합니다. 반복문이 끝난 뒤에는 플래그(flag)를 확인해 숫자를 찾았는지 판단합니다.

다음은 서로 다른 문자 유형을 세는 또 다른 실용 예입니다:

python
# 문자열에서 문자 유형 분석하기
text = "Hello, World! 123"
letters = 0
digits = 0
spaces = 0
other = 0
 
for char in text:
    if char.isalpha():
        letters += 1
    elif char.isdigit():
        digits += 1
    elif char.isspace():
        spaces += 1
    else:
        other += 1
 
print(f"Letters: {letters}")
print(f"Digits: {digits}")
print(f"Spaces: {spaces}")
print(f"Other: {other}")

Output:

Letters: 10
Digits: 3
Spaces: 2
Other: 2

이 반복문은 5장에서 배운 문자열 메서드로 각 문자를 분류합니다. if-elif-else 체인(8장)은 각 문자가 정확히 하나의 카테고리로만 집계되도록 보장합니다.

12.3.2) 인덱스로 문자열 처리하기

때로는 문자와 함께 문자열에서의 위치도 필요합니다. range(len(string))를 사용하면 인덱스를 순회할 수 있습니다:

python
# 특정 문자의 위치 찾기
text = "Mississippi"
search_char = "s"
 
print(f"Looking for '{search_char}' in '{text}':")
for index in range(len(text)):
    if text[index] == search_char:
        print(f"  Found at index {index}")

Output:

Looking for 's' in 'Mississippi':
  Found at index 2
  Found at index 3
  Found at index 5
  Found at index 6

반복문은 0부터 len(text) - 1까지의 인덱스를 순회합니다. 각 인덱스마다 해당 위치의 문자가 찾는 문자와 일치하는지 확인합니다. 이 접근은 무엇이 나타나는지뿐 아니라 어디에 나타나는지도 알아야 할 때 유용합니다.

12.3.3) 다른 시퀀스 타입 순회하기

for 반복문은 Python의 어떤 이터러블(iterable) 시퀀스에도 동작합니다. 이 장에서는 문자열에 집중했지만, 이후 장에서 다른 시퀀스 타입을 배울 것입니다. 예를 들어 14장에서는 어떤 타입의 값이든 여러 개 담을 수 있는 순서 있는 컬렉션인 리스트(list)를 배웁니다. 어떤 타입의 시퀀스를 순회하든 for 반복문의 문법은 동일합니다—반복문이 시퀀스에서 각 항목을 가져오는 일을 자동으로 처리합니다.

12.4) for 반복문에서 breakcontinue 사용하기

12.4.1) for 반복문에서의 break

while 반복문(11장)과 마찬가지로, break 문은 for 반복문을 즉시 종료하고 남은 반복을 건너뜁니다. 찾고 있던 것을 발견했고 더 이상 검색할 필요가 없을 때 유용합니다.

다음은 특정 문자를 찾는 예입니다:

python
# 문자열에서 첫 번째 모음 찾기
text = "Python"
found_vowel = False
 
for char in text:
    if char.lower() in "aeiou":
        print(f"First vowel found: {char}")
        found_vowel = True
        break  # 첫 번째 모음을 찾으면 검색을 중단
        
 
if not found_vowel:
    print("No vowels found")

Output:

First vowel found: o

break가 없으면 첫 번째 모음을 찾은 뒤에도 남은 모든 문자를 계속 검사할 것입니다. break 문은 작업이 끝나는 즉시 멈추므로 코드를 더 효율적으로 만듭니다.

다음은 잘못된 문자가 있는지 확인하여 사용자 입력을 검증하는 실용적인 예입니다:

python
# 사용자 이름에 허용된 문자만 포함되어 있는지 확인하기
username = "alice_123"
allowed = "abcdefghijklmnopqrstuvwxyz0123456789_"
is_valid = True
 
for char in username:
    if char.lower() not in allowed:
        print(f"Invalid character found: '{char}'")
        is_valid = False
        break  # 더 이상 검사할 필요 없음
 
if is_valid:
    print(f"Username '{username}' is valid ✓")
else:
    print(f"Username '{username}' is invalid ✗")

Output:

Username 'alice_123' is valid ✓

반복문은 각 문자를 허용 집합에 대해 검사합니다. 유효하지 않은 문자를 찾으면 문제를 보고하고 즉시 반복문을 빠져나옵니다—유효하지 않다는 것을 알게 된 뒤에는 나머지 사용자 이름을 검사할 필요가 없습니다.

12.4.2) for 반복문에서의 continue

continue 문은 현재 반복(iteration)에서 남은 부분을 건너뛰고 시퀀스의 다음 항목으로 이동합니다. 반복문을 완전히 종료하지 않고 특정 항목을 건너뛰고 싶을 때 유용합니다.

다음은 특정 문자만 처리하는 예입니다:

python
# 문자열에서 자음만 출력하기
word = "Programming"
 
for letter in word:
    if letter.lower() in "aeiou":
        continue  # 모음은 건너뛰기
    print(letter, end="")
print()  # 마지막에 새 줄

Output:

Prgrmmng

반복문이 모음을 만나면 continueprint() 문을 건너뛰고 다음 문자로 이동합니다. 자음만 출력 문에 도달합니다.

다음은 유효하지 않은 데이터를 건너뛰면서 통계를 계산하는 더 실용적인 예입니다. .split() 메서드(6장에서 배웠습니다)는 문자열 리스트를 반환하며, 이는 14장에서 배울 것입니다. 지금은 for 반복문이 그 결과를 순회할 수 있다는 점만 알아두세요:

python
# 유효한 시험 점수(0-100)의 평균 계산하기
# .split() 메서드는 문자열 리스트를 반환합니다(14장)
scores_input = "85 92 -5 78 105 90 88"
valid_scores = 0
total = 0
 
for score_str in scores_input.split():
    score = int(score_str)
    
    if score < 0 or score > 100:
        print(f"Skipping invalid score: {score}")
        continue  # 이 점수는 건너뛰기
    
    valid_scores += 1
    total += score
 
if valid_scores > 0:
    average = total / valid_scores
    print(f"Average of {valid_scores} valid scores: {average:.1f}")
else:
    print("No valid scores to average")

Output:

Skipping invalid score: -5
Skipping invalid score: 105
Average of 5 valid scores: 86.6

반복문은 각 점수 문자열을 처리합니다. 유효하지 않은 점수(음수 또는 100 초과)를 만나면 경고를 출력하고 continue로 그 점수를 합계에 더하는 작업을 건너뜁니다. 이를 통해 유효하지 않은 점수는 무시하면서 유효한 점수는 모두 처리할 수 있습니다.

12.4.3) breakcontinue를 언제 사용할까

break를 사용하는 경우:

  • 무언가를 찾고 있고, 찾는 즉시 멈추고 싶을 때
  • 계속 진행해도 의미 없는 오류 조건을 만났을 때
  • 작업을 완료했고 남은 항목을 처리할 필요가 없을 때

continue를 사용하는 경우:

  • 조건에 따라 특정 항목을 건너뛰고 싶을 때
  • 데이터를 필터링하며 기준을 만족하는 항목만 처리하고 싶을 때
  • 특수 케이스를 초기에 처리하여 if를 깊게 중첩시키는 것을 피하고 싶을 때

breakcontinue는 반복(iteration)의 일반적인 흐름을 언제, 왜 바꾸는지 명시적으로 보여주기 때문에 코드를 더 명확하게 만들 수 있습니다. 하지만 과도하게 사용하면 코드를 따라가기 어려워질 수 있으니, 진짜로 명확성이 좋아질 때 사용하세요.

12.5) for 반복문에서 else 사용하기

12.5.1) for-else 패턴

Python의 for 반복문은 선택적으로 else 절(clause)을 지원합니다. 이는 반복문이 정상적으로 완료된 후, 즉 break 문을 만나지 않고 모든 항목을 끝까지 순회했을 때 실행됩니다. 처음에는 이상해 보일 수 있습니다(“if도 없는데 왜 else지?”). 하지만 “찾았다”와 “끝까지 찾았지만 못 찾았다”를 구분하는 데 유용합니다.

기본 구조는 다음과 같습니다:

python
for item in sequence:
    # 반복문 본문
    if some_condition:
        break
else:
    # break 없이 반복문이 끝까지 완료된 경우에만 실행
    print("Loop completed normally")

else 블록은 반복문이 시퀀스를 모두 소진하며 자연스럽게 종료될 때에만 실행됩니다. break 문이 반복문을 조기에 종료하면 else 블록은 건너뜁니다.

특정 값을 찾는 실용적인 예를 보겠습니다. .split() 메서드(6장)는 문자열 리스트를 반환하며, 이는 14장에서 배울 것입니다:

python
# 목표 숫자 찾기
numbers = "2 4 6 8 10"
target = 7
 
for num_str in numbers.split():
    num = int(num_str)
    if num == target:
        print(f"Found {target}!")
        break
else:
    print(f"{target} not found in the sequence")

Output:

7 not found in the sequence

반복문은 모든 숫자를 검색합니다. 7을 찾지 못하므로 정상적으로 완료되고 else 블록이 실행됩니다. 이제 존재하는 숫자를 검색해 보겠습니다:

python
# 존재하는 목표 숫자 찾기
numbers = "2 4 6 8 10"
target = 6
 
for num_str in numbers.split():
    num = int(num_str)
    if num == target:
        print(f"Found {target}!")
        break
else:
    print(f"{target} not found in the sequence")

Output:

Found 6!

이번에는 6을 찾는 순간 break가 실행되어 else 블록이 완전히 건너뛰어집니다. 이 패턴은 별도의 플래그 변수를 쓰지 않고도 “찾음”과 “못 찾음” 두 경우를 우아하게 처리합니다.

12.5.2) for-else의 실용적 사용처

for-else 패턴은 특히 검색 작업에서 유용합니다. 다음은 문자열이 숫자로만 구성되어 있는지 검증하는 예입니다:

python
# 문자열이 유효한 정수인지 확인하기
user_input = "12345"
 
for char in user_input:
    if not char.isdigit():
        print(f"Invalid: '{char}' is not a digit")
        break
else:
    print(f"'{user_input}' is a valid integer")

Output:

'12345' is a valid integer

입력에 숫자가 아닌 문자가 하나라도 있으면 반복문이 break로 종료되고 else 블록은 실행되지 않습니다. 모든 문자가 숫자라면 반복문이 정상적으로 완료되어 else 블록이 유효함을 확인합니다.

잘못된 입력도 테스트해 보겠습니다:

python
# 문자열이 유효한 정수인지 확인하기(잘못된 경우)
user_input = "123a5"
 
for char in user_input:
    if not char.isdigit():
        print(f"Invalid: '{char}' is not a digit")
        break
else:
    print(f"'{user_input}' is a valid integer")

Output:

Invalid: 'a' is not a digit

12.5.3) for-else와 플래그 변수 비교하기

for-else를 배우기 전에는, 무언가를 찾았는지 추적하기 위해 플래그 변수를 사용했을 수도 있습니다:

python
# 플래그 변수 사용(전통적인 접근)
text = "Python"
found_vowel = False
 
for char in text:
    if char.lower() in "aeiou":
        print(f"Found vowel: {char}")
        found_vowel = True
        break
 
if not found_vowel:
    print("No vowels found")

Output:

Found vowel: o

for-else 패턴은 플래그 변수가 필요 없게 해줍니다:

python
# for-else 사용(더 파이써닉함)
text = "Python"
 
for char in text:
    if char.lower() in "aeiou":
        print(f"Found vowel: {char}")
        break
else:
    print("No vowels found")

Output:

Found vowel: o

두 방법 모두 올바르게 동작하지만, for-else 버전이 더 간결하고 의도를 더 명확하게 표현합니다: “무언가를 찾고, 못 찾으면 이것을 하라.” else 절은 “못 찾음” 케이스를 직접적으로 나타냅니다.

12.6) for 반복문과 while 반복문 중 선택하기

12.6.1) for 반복문을 언제 사용할까

다음과 같은 경우 for 반복문을 사용하세요:

1. 컬렉션(collection)의 각 항목을 처리할 때:

python
# 문자열의 각 문자를 처리하기
message = "Hello"
for char in message:
    print(char.upper())

Output:

H
E
L
L
O

2. 특정 횟수만큼 동작을 반복해야 할 때:

python
# 테두리 줄 출력하기
for i in range(40):
    print("-", end="")
print()

Output:

----------------------------------------

3. 숫자 범위를 순회할 때:

python
# 5의 팩토리얼 계산하기
factorial = 1
for n in range(1, 6):
    factorial *= n
print(f"5! = {factorial}")

Output:

5! = 120

4. 무엇을 순회할지 미리 알고 있을 때:

python
# 알고 있는 값 시퀀스 처리하기
grades = "A B C D F"
for grade in grades.split():
    print(f"Grade: {grade}")

Output:

Grade: A
Grade: B
Grade: C
Grade: D
Grade: F

for 반복문의 핵심 특성은 확정 반복(definite iteration)을 한다는 것입니다—몇 개의 항목이 있는지는 미리 모를 수도 있지만, 어떤 시퀀스를 순회하는지는 알고 있습니다.

12.6.2) while 반복문을 언제 사용할까

다음과 같은 경우 while 반복문을 사용하세요:

1. 조건이 바뀔 때까지 반복할 때:

python
# 유효한 입력을 받을 때까지 계속 묻기
while True:
    age_input = input("Enter your age: ")
    if age_input.isdigit():
        age = int(age_input)
        if age > 0:
            print(f"Age recorded: {age}")
            break
    print("Please enter a valid positive number")

2. 몇 번 반복해야 할지 모를 때:

python
# 1000을 초과하기 전까지 숫자를 몇 번이나 2배로 만들 수 있는지 세기
number = 1
count = 0
while number <= 1000:
    number *= 2
    count += 1
print(f"Doubled {count} times to reach {number}")

Output:

Doubled 10 times to reach 1024

3. 반복이 복잡한 조건에 의존할 때:

python
# 플레이어 체력이 감소하는 간단한 게임 시뮬레이션
health = 100
turn = 0
 
while health > 0 and turn < 10:
    damage = 15
    health -= damage
    turn += 1
    print(f"Turn {turn}: Health = {health}")
 
if health <= 0:
    print("Game over!")
else:
    print("Survived 10 turns!")

Output:

Turn 1: Health = 85
Turn 2: Health = 70
Turn 3: Health = 55
Turn 4: Health = 40
Turn 5: Health = 25
Turn 6: Health = 10
Turn 7: Health = -5
Game over!

4. 반복 로직을 더 세밀하게 제어해야 할 때:

python
# 문자열을 처리하되 연속 중복은 건너뛰기
text = "bookkeeper"
index = 0
 
while index < len(text):
    char = text[index]
    print(char, end="")
    
    # 연속으로 같은 문자를 건너뛰기
    while index < len(text) and text[index] == char:
        index += 1
 
print()

Output:

bokeper

while 반복문의 핵심 특성은 불확정 반복(indefinite iteration)입니다—조건이 거짓이 될 때까지 계속하지만, 그 시점이 언제일지는 미리 모를 수 있습니다.

12.6.3) forwhile 사이 변환하기

많은 문제는 어느 반복문으로도 풀 수 있습니다. 다음은 같은 작업을 두 가지 방식으로 구현한 것입니다:

python
# for 반복문 사용: 1부터 10까지 합산하기
total = 0
for number in range(1, 11):
    total += number
print(f"Sum (for loop): {total}")
 
# while 반복문 사용: 1부터 10까지 합산하기
total = 0
number = 1
while number <= 10:
    total += number
    number += 1
print(f"Sum (while loop): {total}")

Output:

Sum (for loop): 55
Sum (while loop): 55

둘 다 같은 결과를 만들지만, for 반복문이 더 간결하고 실수하기도 어렵습니다—카운터 증가를 잊을 위험이 없습니다. 둘 중 어느 것을 사용해도 된다면 for 반복문을 우선하세요.

하지만 어떤 문제는 while로 표현하는 편이 더 자연스럽습니다:

python
# 1000보다 큰 첫 번째 2의 거듭제곱 찾기
power = 1
exponent = 0
 
while power <= 1000:
    exponent += 1
    power = 2 ** exponent
 
print(f"2^{exponent} = {power} (first power of 2 > 1000)")

Output:

2^10 = 1024 (first power of 2 > 1000)

이 문제는 필요한 반복 횟수를 미리 알 수 없기 때문에 for 반복문에 자연스럽게 맞지 않습니다—조건을 만족하는 값을 찾는 검색 작업입니다.


이 장에서는 시퀀스를 순회하는 깔끔하고 강력한 방법을 제공하는 Python의 for 반복문을 살펴보았습니다. range()가 카운팅 작업을 위한 숫자 시퀀스를 어떻게 생성하는지, breakcontinue로 반복 흐름을 어떻게 제어하는지, 그리고 for-else 패턴이 검색 작업을 어떻게 우아하게 처리하는지도 배웠습니다. 또한 반복 작업의 성격에 따라 for 반복문과 while 반복문 중 무엇을 선택해야 하는지도 살펴봤습니다.

for 반복문은 Python에서 가장 자주 사용되는 기능 중 하나입니다. Python 학습을 계속하는 동안 for 반복문을 끊임없이 사용하게 될 것입니다—파일에서 데이터를 처리하고, 리스트(list)와 딕셔너리(dictionary)로 작업하고, 정보 컬렉션(collection)을 변환하는 등에서요. 다음 장에서는 값에 따라 결정을 내리는 또 다른 방법을 제공하는 Python의 match 문(statement)을 살펴보겠습니다. 이는 특정 유형의 문제에서 긴 if-elif 체인에 대한 더 구조화된 대안을 제공합니다.


© 2025. Primesoft Co., Ltd.
support@primesoft.ai