4-2 반복문 for: 시퀀스 데이터 순회하기

4-2 반복문 for: 시퀀스 데이터 순회하기

← 목차로 돌아가기

썸네일

프로그래밍에서 반복 작업은 피할 수 없는 부분입니다. 특히 여러 개의 데이터를 순서대로 처리해야 할 때, 이 과정을 효율적으로 자동화하는 것이 중요합니다. 파이썬의 `for` 반복문은 이러한 시퀀스 데이터를 다루는 데 가장 강력하고 직관적인 도구 중 하나입니다.

for 반복문이란 무엇인가요?

`for` 반복문은 파이썬에서 리스트, 튜플, 문자열 등 시퀀스(Sequence) 데이터를 효율적으로 순회하며 각 요소에 특정 작업을 수행할 때 사용됩니다. 시퀀스란 여러 개의 요소가 순서대로 나열된 데이터 구조를 말합니다. 저는 현업에서 데이터 분석을 하거나 자동화 스크립트를 작성할 때, 수많은 데이터 묶음에서 특정 조건을 만족하는 요소를 찾거나 모든 요소에 동일한 처리를 적용해야 할 때 `for` 반복문을 밥 먹듯이 사용합니다. 같은 작업을 수동으로 여러 번 반복하는 대신, `for` 반복문을 사용하면 코드를 간결하고 오류 없이 유지할 수 있습니다.

for 반복문의 기본 구조

`for` 반복문은 `for 요소 변수 in 시퀀스:`와 같은 간단한 형태로 시퀀스 내의 각 항목을 하나씩 `요소 변수`에 할당하며 블록을 실행합니다.

기본적인 `for` 반복문의 구조는 다음과 같습니다.

for 변수 in 시퀀스_데이터:
    # 시퀀스_데이터의 각 요소에 대해 실행할 코드 블록
    # 이 코드 블록에서는 '변수'가 현재 순회 중인 요소를 나타냅니다.

여기서 `변수`는 시퀀스 데이터의 각 요소를 임시로 저장하는 역할을 합니다. 반복문이 한 번 실행될 때마다 `시퀀스_데이터`의 다음 요소가 `변수`에 할당됩니다. 예를 들어, 리스트의 모든 항목을 출력하는 코드를 살펴보겠습니다.

과일_목록 = ["사과", "바나나", "체리"]
for 과일 in 과일_목록:
    print(f"{과일} 맛있어요!")

이 코드는 `과일_목록`의 “사과”, “바나나”, “체리”를 각각 `과일` 변수에 할당하며 `print()` 함수를 실행합니다. 결과적으로 세 줄의 문장이 출력되죠.

파이썬은 들여쓰기를 통해 코드 블록을 구분하므로, `for` 문 아래에 실행될 모든 코드는 반드시 같은 깊이로 들여쓰기 되어야 합니다. 이는 첫 번째 프로그램 작성에서도 강조했던 중요한 문법 규칙입니다.

다양한 시퀀스 데이터 순회하기

`for` 반복문은 리스트뿐만 아니라 문자열, 튜플, 딕셔너리(키 또는 값), 세트 등 파이썬의 다양한 시퀀스 및 이터러블(iterable) 객체에 적용할 수 있습니다. 파이썬의 강력함은 이렇게 일관된 방식으로 여러 데이터 타입을 다룰 수 있다는 점에 있습니다.

문자열 순회하기

문자열도 사실은 문자들의 시퀀스입니다. 따라서 `for` 반복문을 사용하여 문자열의 각 문자를 하나씩 순회할 수 있습니다.

단어 = "Python"
for 글자 in 단어:
    print(글자)

이 코드는 “P”, “y”, “t”, “h”, “o”, “n”을 각각 한 줄씩 출력합니다. 문자열 다루기 챕터에서 배웠듯이 문자열도 인덱스를 가집니다.

튜플 순회하기

튜플은 리스트와 유사하게 순서가 있는 데이터 묶음이지만, 한 번 생성되면 변경할 수 없다는 특징이 있습니다. `for` 반복문으로 튜플의 요소를 순회하는 방법은 리스트와 동일합니다.

좌표 = (10, 20, 30)
for 값 in 좌표:
    print(f"좌표 값: {값}")

이 예시는 `좌표` 튜플의 각 요소를 순서대로 출력합니다. 튜플에 대한 자세한 내용은 튜플: 변경 불가능한 데이터 묶음의 이해 챕터에서 확인할 수 있습니다.

딕셔너리 순회하기

딕셔너리는 키-값 쌍으로 데이터를 저장합니다. `for` 반복문으로 딕셔너리를 순회할 때는 기본적으로 키(key)를 순회하게 됩니다. 하지만 `.keys()`, `.values()`, `.items()` 메서드를 활용하여 키, 값, 또는 키와 값을 동시에 순회할 수 있습니다.

학생_점수 = {"민수": 90, "영희": 85, "철수": 92}

print("--- 키(key) 순회 ---")
for 이름 in 학생_점수:
    print(이름) # 기본적으로 키 순회

print("--- 값(value) 순회 ---")
for 점수 in 학생_점수.values():
    print(점수)

print("--- 키-값 쌍(item) 순회 ---")
for 이름, 점수 in 학생_점수.items():
    print(f"{이름}의 점수: {점수}점")

딕셔너리 활용법은 딕셔너리: 키-값 쌍으로 데이터 저장하기 챕터에서 더 깊이 다룹니다.

range() 함수로 숫자 범위 순회하기

`range()` 함수는 특정 범위의 정수 시퀀스를 생성하여 `for` 반복문과 함께 사용하면 정해진 횟수만큼 반복 작업을 수행할 때 매우 유용합니다. 데이터 자체를 순회하는 것이 아니라, 특정 횟수만큼 반복해야 할 때 저는 `range()` 함수를 즐겨 사용합니다. 이는 마치 ‘1부터 10까지 세면서 무언가를 해라’와 같은 지시를 내리는 것과 같습니다.

  • `range(stop)`: 0부터 `stop-1`까지의 정수 시퀀스를 생성합니다.
  • `range(start, stop)`: `start`부터 `stop-1`까지의 정수 시퀀스를 생성합니다.
  • `range(start, stop, step)`: `start`부터 `stop-1`까지 `step` 간격으로 정수 시퀀스를 생성합니다.
print("--- 0부터 4까지 ---")
for i in range(5):
    print(i)

print("--- 1부터 5까지 ---")
for i in range(1, 6):
    print(i)

print("--- 0부터 9까지, 2칸씩 건너뛰기 ---")
for i in range(0, 10, 2):
    print(i)

이처럼 `range()`는 특정 횟수만큼 반복할 때 유용하며, 인덱스를 기반으로 리스트의 특정 요소에 접근할 때도 사용됩니다. 예를 들어, 리스트의 특정 위치에 있는 값을 변경하고 싶을 때 `range(len(리스트))`를 활용할 수 있습니다.

`enumerate()` 함수로 인덱스와 값 함께 얻기

`enumerate()` 함수는 시퀀스를 순회할 때 각 요소의 인덱스(위치)와 값을 동시에 가져올 수 있게 하여, 특정 위치의 요소에 접근하거나 번호를 매길 때 편리합니다. 저는 UI 요소를 만들 때나, 로그를 기록할 때 몇 번째 항목인지 함께 표시해야 할 경우 `enumerate()`를 자주 활용합니다. 이는 시퀀스의 요소뿐만 아니라 해당 요소의 순번(인덱스)도 함께 필요한 상황에 빛을 발합니다.

재료_목록 = ["계란", "밀가루", "설탕", "버터"]

for 인덱스, 재료 in enumerate(재료_목록):
    print(f"{인덱스 + 1}번째 재료: {재료}")

위 코드를 실행하면 각 재료 앞에 1부터 시작하는 번호가 붙어 출력됩니다. 기본적으로 인덱스는 0부터 시작하지만, `enumerate()` 함수의 두 번째 인자로 시작 인덱스를 지정할 수도 있습니다.

for 인덱스, 재료 in enumerate(재료_목록, start=1):
    print(f"{인덱스}번째 재료: {재료}")

흔히 하는 실수와 해결 팁

`for` 반복문을 사용할 때 들여쓰기 오류나 시퀀스 변경 시 발생하는 문제는 초보자들이 자주 겪는 상황으로, 이들을 미리 알고 대처하면 효율적인 코드 작성이 가능합니다. 저도 처음 파이썬을 배울 때 들여쓰기 때문에 정말 많은 시간을 보냈습니다.

들여쓰기 오류 (IndentationError)

파이썬은 다른 언어와 달리 중괄호 `{}` 대신 들여쓰기로 코드 블록을 구분합니다. 따라서 `for` 반복문 아래에 오는 코드 블록의 들여쓰기가 일치하지 않으면 `IndentationError`가 발생합니다.

# 잘못된 예시
my_list = [1, 2, 3]
for item in my_list:
print(item) # 이 부분이 들여쓰기 되어 있지 않아 오류 발생

올바른 코드는 `print(item)` 앞에 공백 4칸이나 탭 한 번으로 들여쓰기 하는 것입니다. 통합 개발 환경(IDE)인 VS Code나 PyCharm을 사용하면 이러한 들여쓰기 오류를 자동으로 감지하고 수정하는 데 도움을 받을 수 있습니다. 통합 개발 환경(IDE) 선택과 설정 챕터에서 IDE의 이점을 확인해 보세요.

반복 중 시퀀스 변경

`for` 반복문이 순회하고 있는 시퀀스(예: 리스트)의 요소를 반복문 안에서 직접 추가하거나 삭제하는 것은 예기치 않은 결과를 초래할 수 있습니다. 반복의 기준이 되는 시퀀스가 도중에 변경되면서 건너뛰거나 중복 처리되는 문제가 발생하기 때문입니다.

# 위험한 예시: 반복 중 리스트 변경
숫자_리스트 = [1, 2, 3, 4, 5]
for 숫자 in 숫자_리스트:
    if 숫자 % 2 == 0:
        숫자_리스트.remove(숫수) # 리스트의 길이가 변경되어 오류 가능성
print(숫자_리스트) # 예상과 다른 결과가 나올 수 있습니다.

이러한 문제를 피하려면, 시퀀스를 변경해야 할 경우 다음 두 가지 방법 중 하나를 사용하는 것이 좋습니다.

  1. 변경할 시퀀스의 복사본을 순회하고, 원본을 변경합니다.
  2. 새로운 시퀀스를 만들어 조건을 만족하는 요소만 추가합니다.
# 해결책 1: 복사본 순회
원본_리스트 = [1, 2, 3, 4, 5]
새_리스트 = []
for 숫자 in 원본_리스트[:]: # 슬라이싱을 이용해 복사본 생성
    if 숫자 % 2 != 0:
        새_리스트.append(숫자)
print(새_리스트)

# 해결책 2: 새로운 리스트 생성
원본_리스트 = [1, 2, 3, 4, 5]
홀수_리스트 = [숫자 for 숫자 in 원본_리스트 if 숫자 % 2 != 0] # 리스트 컴프리헨션 (고급 주제)
print(홀수_리스트)

아직 리스트 컴프리헨션이 낯설다면, 첫 번째 해결책처럼 복사본을 만들어 순회하거나 새로운 리스트에 담는 방법을 사용해 보세요. 이는 예상치 못한 오류를 줄이는 좋은 습관입니다.

for 반복문의 실제 활용 예제

`for` 반복문은 단순히 값을 출력하는 것을 넘어, 데이터 처리, 필터링, 계산 등 다양한 프로그래밍 작업의 핵심 요소로 활용됩니다. 제가 실제 프로젝트에서 사용했던 간단한 예시들을 통해 그 활용성을 살펴보겠습니다.

리스트에서 특정 조건의 요소 찾기

특정 조건에 맞는 요소를 리스트에서 찾아내야 할 때 `for` 반복문과 조건문(if)을 함께 사용합니다.

성적_목록 = [85, 92, 78, 95, 88, 65]
합격_점수 = 80
합격자_성적 = []

for 성적 in 성적_목록:
    if 성적 >= 합격_점수:
        합격자_성적.append(성적)

print(f"합격자 성적: {합격자_성적}") # 출력: 합격자 성적: [85, 92, 95, 88]

이 코드는 `성적_목록`에서 80점 이상인 성적만 골라 `합격자_성적` 리스트에 추가합니다. 실제로는 더 복잡한 조건이나 데이터 필터링에 활용되곤 합니다.

모든 요소에 연산 적용하기

리스트의 모든 숫자형 요소에 동일한 연산을 적용하고 싶을 때도 `for` 반복문이 유용합니다. 예를 들어, 모든 시험 점수에 보너스 점수를 더하는 상황입니다.

초기_점수 = [70, 80, 90]
보너스 = 5
최종_점수 = []

for 점수 in 초기_점수:
    최종_점수.append(점수 + 보너스)

print(f"최종 점수: {최종_점수}") # 출력: 최종 점수: [75, 85, 95]

이처럼 숫자형 데이터를 다룰 때 `for` 반복문은 일괄적인 계산을 가능하게 합니다.

텍스트 데이터 처리 (문자열 리스트)

여러 문장으로 이루어진 리스트에서 특정 단어의 출현 횟수를 세거나, 각 문장의 길이를 계산하는 등 텍스트 데이터를 처리하는 데도 `for` 반복문은 핵심적인 역할을 합니다.

문장_리스트 = [
    "파이썬은 배우기 쉽고 강력합니다.",
    "데이터 분석에 파이썬이 많이 사용됩니다.",
    "자동화를 위한 파이썬 스크립트."
]

총_글자수 = 0
특정_단어_횟수 = 0
찾을_단어 = "파이썬"

for 문장 in 문장_리스트:
    총_글자수 += len(문장)
    특정_단어_횟수 += 문장.count(찾을_단어)

print(f"전체 문장의 총 글자수: {총_글자수}자")
print(f"'{찾을_단어}' 단어 출현 횟수: {특정_단어_횟수}회")

이 예제는 여러 문장의 총 글자수를 계산하고, 특정 단어가 얼마나 등장하는지 세어줍니다. 저는 이렇게 수많은 텍스트 파일에서 원하는 정보를 추출할 때 `for` 반복문과 문자열 메서드를 함께 사용합니다.

`for` 반복문은 파이썬 프로그래밍에서 데이터를 다루는 데 있어 없어서는 안 될 기본기입니다. 다양한 시퀀스 데이터를 순회하고, `range()`나 `enumerate()` 같은 내장 함수와 결합하여 무궁무진한 활용 가능성을 가집니다. 이제 `for` 반복문에 익숙해지셨다면, 다음 챕터에서는 다른 종류의 반복문인 `while` 반복문을 통해 조건에 따라 반복을 제어하는 방법을 알아보겠습니다.

자주 묻는 질문 (FAQ)

Q1: `for`와 `while` 반복문의 주요 차이점은 무엇인가요?

A1: `for` 반복문은 주로 리스트, 문자열과 같은 시퀀스 데이터의 모든 요소를 하나씩 순회할 때 사용하며, 반복 횟수가 시퀀스의 길이에 의해 정해지는 경우가 많습니다. 반면 `while` 반복문은 특정 조건이 참(True)인 동안 코드를 계속 반복 실행하며, 반복 횟수가 명확하지 않고 조건에 따라 반복을 멈춰야 할 때 주로 사용됩니다.

Q2: 딕셔너리를 `for` 문으로 순회할 때 키와 값을 동시에 얻는 방법은?

A2: 딕셔너리의 `.items()` 메서드를 사용하면 `for` 반복문에서 키와 값을 튜플 형태로 동시에 얻을 수 있습니다. 예를 들어, `for key, value in my_dict.items():`와 같이 사용하면 됩니다.

Q3: `range()` 함수 대신 `for` 문으로 0부터 N까지 반복할 수 있나요?

A3: `range()` 함수는 0부터 N-1까지의 정수를 효율적으로 생성하여 반복 횟수를 지정할 때 최적화된 방법입니다. 물론 `my_list = [0, 1, 2, …, N-1]`와 같은 리스트를 만들어서 순회할 수도 있지만, 메모리 효율성과 가독성 면에서 `range()`를 사용하는 것이 일반적이고 권장됩니다.

Q4: `for` 반복문 안에서 리스트의 요소를 추가하거나 삭제해도 되나요?

A4: `for` 반복문이 현재 순회하고 있는 리스트의 요소를 반복문 안에서 직접 추가하거나 삭제하는 것은 일반적으로 권장되지 않습니다. 반복의 기준이 되는 리스트의 길이가 변경되어 예상치 못한 결과(요소 건너뜀, 무한 반복 등)가 발생할 수 있기 때문입니다. 대신, 원본 리스트의 복사본을 순회하거나, 조건을 만족하는 요소를 새로운 리스트에 추가하는 방식을 사용하는 것이 안전합니다.

참고 자료

  1. [1] Python 공식 튜토리얼 — 제어 흐름 도구와 함수 정의 — https://docs.python.org/ko/3/tutorial/controlflow.html

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다