본문 바로가기
Artificial Intelligence/60. Python

[PYTHON] Iterable과 Iterator의 개념 완벽 정리 : 반복 가능한 객체의 마법

by Papa Martino V 2026. 2. 6.
728x90

Iterable과 Iterator
Iterable과 Iterator

 

파이썬을 배우다 보면 가장 먼저 접하는 제어문 중 하나가 바로 for 루프입니다. 우리는 리스트(List)나 문자열(String)을 for 문에 넣고 아주 당연하게 데이터를 하나씩 꺼내 씁니다. 하지만 이 단순해 보이는 동작 뒤에는 파이썬의 핵심 설계 철학인 '반복 프로토콜(Iteration Protocol)'이 숨어 있습니다. 많은 초보 개발자들이 Iterable(반복 가능한 객체)Iterator(반복자)를 혼동하거나 동일한 것으로 간주하곤 합니다. 하지만 이 둘의 차이를 명확히 이해하는 것은 메모리 효율적인 코드를 작성하고, 파이썬의 고급 기능인 제너레이터(Generator)를 마스터하기 위한 필수 관문입니다. 본 가이드에서는 두 개념의 정의부터 작동 원리, 그리고 실전 최적화 팁까지 전문적인 식견으로 파헤쳐 봅니다.


1. Iterable: "반복될 수 있는 잠재력"

Iterable은 말 그대로 '반복 가능한' 객체를 의미합니다. 좀 더 기술적으로 정의하자면, 자신의 멤버를 한 번에 하나씩 반환할 수 있는 능력을 가진 객체입니다. 파이썬의 리스트, 튜플, 딕셔너리, 집합, 문자열은 모두 대표적인 Iterable입니다.

  • 핵심 조건: __iter__() 메서드를 가지고 있거나, 인덱스 0부터 시작하는 __getitem__() 메서드를 가지고 있어야 합니다.
  • 작동 방식: Iterable 자체는 데이터를 한꺼번에 들고 있는 '창고'와 같습니다. iter() 함수에 전달되면 데이터를 하나씩 꺼내 줄 '일꾼(Iterator)'을 생성하여 반환합니다.

2. Iterator: "실제로 반복을 수행하는 일꾼"

Iterator는 Iterable 객체에서 값을 차례대로 꺼내는 '상태(State)'를 가진 객체입니다. Iterable이 데이터 집합이라면, Iterator는 현재 어디까지 읽었는지를 기억하고 다음 요소를 가져오는 역할을 수행합니다.

  • 핵심 조건: __next__() 메서드와 __iter__() 메서드를 모두 구현해야 합니다. (이를 Iterator Protocol이라 합니다.)
  • 특징: next() 함수를 호출할 때마다 다음 요소를 반환하며, 더 이상 반환할 값이 없으면 StopIteration 예외를 발생시킵니다.
  • 일회성: 한 번 끝까지 순회한 Iterator는 다시 사용할 수 없습니다. 다시 순회하려면 새로운 Iterator를 생성해야 합니다.

3. Iterable vs Iterator 비교 분석

두 개념의 차이점을 한눈에 파악할 수 있도록 비교표로 정리하였습니다.

구분 Iterable (반복 가능한 객체) Iterator (반복자)
개념 반복될 수 있는 데이터의 집합/컨테이너 데이터를 하나씩 꺼내는 도구/포인터
메서드 __iter__() __iter__() + __next__()
상태 유지 유지하지 않음 (정적 데이터) 현재 위치를 기억함 (동적 상태)
생성 방법 리스트, 튜플 등 리터럴 선언 iter(iterable_obj) 호출
예시 [1, 2, 3], "hello" list_iterator 객체
중요 포인트: 모든 Iterator는 __iter__()를 구현하여 자기 자신을 반환하므로 모든 Iterator는 Iterable입니다. 하지만 모든 Iterable이 Iterator인 것은 아닙니다. (예: 리스트는 Iterable이지만 next()를 바로 쓸 수 없으므로 Iterator가 아님)

4. 실전 코드 예제 (Sample Examples)

예제 1: for 문의 내부 작동 원리 구현

우리가 for x in [1, 2, 3]을 실행할 때 파이썬 내부에서 일어나는 과정을 while 문으로 재현해 보겠습니다.

# Iterable 리스트
my_list = [10, 20, 30]

# 1. Iterable로부터 Iterator 생성
my_iter = iter(my_list)

# 2. 반복 실행
while True:
    try:
        # 3. 다음 요소 가져오기
        element = next(my_iter)
        print(element)
    except StopIteration:
        # 4. 더 이상 요소가 없으면 종료
        break

예제 2: 커스텀 Iterator 클래스 만들기

제곱수를 생성하는 반복자를 직접 구현하여 내부 구조를 이해해 봅니다.

class SquareIterator:
    def __init__(self, limit):
        self.limit = limit
        self.current = 1

    def __iter__(self):
        return self

    def __next__(self):
        if self.current <= self.limit:
            result = self.current ** 2
            self.current += 1
            return result
        else:
            raise StopIteration

# 사용 예시
squares = SquareIterator(5)
for num in squares:
    print(num) # 1, 4, 9, 16, 25 출력

5. 왜 이 개념이 중요한가? (성능과 효율)

리스트와 같은 Iterable은 모든 데이터를 메모리에 미리 적재해야 합니다. 만약 10억 개의 숫자를 다룬다면 메모리가 부족해 프로그램이 멈출 것입니다. 하지만 Iterator를 활용하면 '지연 평가(Lazy Evaluation)'가 가능해집니다. 즉, 값이 필요한 그 순간에만 메모리를 사용하므로 메모리 사용량을 획기적으로 줄일 수 있습니다.


내용 출처 및 참고 자료

  • Python Software Foundation. "Glossary - Iterable & Iterator". docs.python.org.
  • Ramalho, Luciano. "Fluent Python: Clear, Concise, and Effective Programming". O'Reilly Media.
  • Real Python. "Python Iterators: A Step-By-Step Guide". realpython.com.
728x90