IT/Python

[Python] Iterator와 Generator

돔녕 2025. 4. 3. 15:06

오늘 인턴 면접을 봤는데 Iterator와 Generator에 대한 질문이 나왔다.

뭔가 반복문 관련된 생각은 나는데, 확신이 없어 대답을 제대로 못한 것 같다😩

면접보고 아직 부족하다고 많이 느꼈다..!

앞으로 이런 일이 발생하지 않기 위해 미리 정리해두어야겠다.

 


파이썬에서 데이터를 순차적으로 처리할 땐 보통 for문을 사용한다.

for문 안에는 iteratorgenerator라는 도구가 있다. 

https://wikidocs.net/194288 를 참고해서 간단히 정리해보려고 한다.

 

💡 이터레이터(iterator)란?

next() 함수 호출 시 계속 그다음 값을 반환하는 객체로,

이터레이터는 데이터를 차례대로 하나씩 꺼낼 수 있는 객체다.
리스트, 튜플, 문자열 등은 모두 iterable한 객체지만, next()를 직접 쓸 순 없다.

my_list = [1, 2, 3, 4, 5]
list_iterator = iter(my_list)

print(next(list_iterator))  # 출력: 1
print(next(list_iterator))  # 출력: 2

이터레이터의 끝에 도달하면 StopIteration 예외가 발생하고, 이를 이용해 for문을 사용하여 이터레이터를 전체 순회할 수 있다.

for item in list_iterator:
    print(item)

 

-> 대용량 데이터 처리파일 스트림을 다룰 때 유용

 

이터레이터 만들기

- 짝수만 출력하는 이터레이터

class EvenNumbers:
    def __init__(self, n):
        self.n = n
        self.current = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.current > self.n:
            raise StopIteration
        even_number = self.current
        self.current += 2
        return even_number

even_iterator = EvenNumbers(10)
for num in even_iterator:
    print(num)

출력 결과:
0
2
4
6
8
10

- 피보나치 수열 예제 (이터레이터)

class Fibonacci:
    def __init__(self, n):
        self.n = n
        self.current = 0
        self.prev = 0
        self.next = 1

    def __iter__(self):
        return self

    def __next__(self):
        if self.current > self.n:
            raise StopIteration
        fib_number = self.prev
        self.prev, self.next = self.next, self.prev + self.next
        self.current += 1
        return fib_number

fib_iterator = Fibonacci(10)
for num in fib_iterator:
    print(num)

출력 결과:
0

1

1

2

3

5

8

13

21

34

55

 

💡제너레이터(generator)란?

이터레이터를 생성해주는 객체로,

yield를 사용하면 함수도 이터레이터처럼 사용할 수 있다.

- 피보나치 수열 예제 (제너레이터)

def fibonacci(n):
    prev, next = 0, 1
    for _ in range(n + 1):
        yield prev
        prev, next = next, prev + next

fib_generator = fibonacci(10)

for num in fib_generator:
    print(num)

출력 결과:
0

1

1

2

3

5

8

13

21

34

55

 

yield는 호출될 때마다 함수 실행을 잠시 멈췄다가, 다시 이어서 실행
상태를 기억하는 일시정지 기능이라고 생각하기

 

제너레이터 표현식

리스트 컴프리헨션처럼 간결한 표현이 가능하고 메모리 효율도 뛰어나다.

even_numbers = (x for x in range(1, 11) if x % 2 == 0)

for num in even_numbers:
    print(num)

출력 결과:
2

4

6

8

10

 

💡이터레이터 / 제너레이터 비교하기

항목 이터레이터 제너레이터
구현 방식 __iter__(), __next__() 클래스 구현 yield 함수 또는 표현식
코드 작성량 상대적으로 길고 복잡 간결하고 직관적
메모리 효율 조건에 따라 다름 높음 (lazy evaluation)
상태 저장 직접 구현 필요 자동 상태 기억

 

이터레이터: 데이터 순차 접근을 위한 객체. 클래스 작성 필요 -> 복잡한 상태 유지, 사용자 정의 반복 로직

제너레이터: yield로 간단하게 이터레이터 구현 -> 간단한 숫자처리

제너레이터 표현식: 메모리 절약 + 깔끔한 코드 -> 무한 시퀀스, 대용량 데이터

 

'IT > Python' 카테고리의 다른 글

[Python] 공공데이터포털 OpenAPI 사용하기  (0) 2025.02.11