Python/Python 기초

[Python] 이터레이터( Iterator ), 제너레이터( Generator )

죵욜이 2024. 12. 2. 16:27

이터러블 ( Iterable )

하나씩 차례대로 값을 꺼내올 수 있는 객체를 말한다.

 

  • 정의: 반복 가능한 객체로, for 루프에서 순회할 수 있는 객체입니다.
    예를 들어, 리스트, 튜플, 문자열, 딕셔너리, 세트 등이 이에 해당합니다.
  • 특징:
    •  __iter__()  메서드를 구현해야 합니다. 이 메서드는 이터레이터를 반환합니다.
    • 순회할 수 있는 데이터를 제공하지만, 데이터를 실제로 순회하는 역할은 이터레이터가 합니다.
iterable = [1, 2, 3]  # 리스트는 이터러블
for item in iterable:
    print(item)  # 1, 2, 3 출력

 


이터레이터( Iterator )

이터러블한 객체의 요소를 하나씩 꺼내오는 객체를 말한다.

 

  • 정의: 이터러블 객체에서  __iter__() 를 호출하여 얻을 수 있는 객체로,  __next__()  메서드를 통해 데이터를 하나씩 반환합니다.
  • 특징:
    •  __iter__()  메서드: 이터레이터 자신을 반환합니다. (이터레이터는 스스로 이터러블이기도 합니다.)
    •  __next__()  메서드: 다음 값을 반환하며, 더 이상 반환할 값이 없으면  StopIteration  예외를 발생시킵니다.
iterable = [1, 2, 3]
iterator = iter(iterable)  # 이터레이터 생성
print(next(iterator))  # 1
print(next(iterator))  # 2
print(next(iterator))  # 3
print(next(iterator))  # StopIteration 예외 발생
더보기
class MyIterator:
    def __init__(self, data):
        self.data = data
        self.index = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.index < len(self.data):
            result = self.data[self.index]
            self.index += 1
            return result
        else:
            raise StopIteration

# 이터레이터 사용
my_iter = MyIterator([1, 2, 3])
for item in my_iter:
    print(item)

제너레이터 ( Generator )

이터레이터를 생성하는 간단한방법으로, 함수 형태로 작성

상태를 유지하면서 데이터를 하나씩 반환하므로, 메모리를 절약하고 효율적으로 데이터 처리가 가능

 

 

  •  yield  키워드 사용:
    • 제너레이터 함수에서 값을 반환할 때  yield 를 사용합니다.
    •  yield 를 호출하면 현재 함수 상태를 저장하고, 호출한 곳으로 값을 반환합니다.
    • 다음 호출 시 이전 상태에서 다시 실행을 이어갑니다.
  • 이터레이터 구현:
    • 제너레이터 함수는 자동으로  __iter__() 와  __next__()  메서드를 구현한 객체를 반환합니다.
    • 따라서 이터레이터처럼 사용할 수 있습니다.
  • 지연 계산(Lazy Evaluation):
    • 값을 필요할 때마다 하나씩 생성합니다.
    • 대량의 데이터를 처리할 때 메모리 사용을 최소화합니다.
def simple_generator():
    yield 1
    yield 2
    yield 3

# 제너레이터 사용
gen = simple_generator()
print(next(gen))  # 1
print(next(gen))  # 2
print(next(gen))  # 3
print(next(gen))  # StopIteration 예외 발생

 


 

제너레이터의 내부 동작

제너레이터는 함수 실행을 중단(pause) 하고 상태를 유지한 뒤, 

필요한 값을 생성(resume) 합니다.

  1.  next()  호출 ->  yield  까지 실행 -> 값 반환 -> 실행 멈춤
  2. 다시  next()  호출 -> 멈췄던 위치에서 실행 재개 -> 다음  yield  까지 실행

제너레이터 표현식

  • 리스트 컴프리헨션과 비슷한 문법으로 제너레이터 작성 가능
  • 제너레이터 표현식은  ()  를 사용
gen_exp = (x * x for x in range(5))
for value in gen_exp:
    print(value)
# 출력
0
1
4
9
16

요약

제너레이터와 이터레이터는 상당히 비슷하다.

 

클래스를 이용해 이터레이터를 작성하면 좀 더 복잡한 행동을 구현할 수 있다.

 

이와 달리 제너레이터를 이용하면 간단하게 이터레이터를 만들 수 있다.

 

따라서 이터레이터의 성격에 따라 클래스로 만들 것인지, 제너레이터로 만들 건인지를 선택해야함!