이터레이터와 제너레이터는 파이썬에서 시퀀스를 효율적으로 처리하기 위한 기반이다. 역사적으로 파이썬은 데이터 스트림 작업을 간소화하고 많은 컬렉션을 메모리에 과도하게 저장하는 것을 피하려고 했다. 우선 __iter__ 및 __next__ 프로토콜을 통해 이터레이터 지원이 등장하였고, 그 이후 yield 기반으로 가장 간단한 이터레이터를 생성할 수 있는 제너레이터가 도입되었다.
문제: 대량의 데이터를 처리해야 하는 경우가 많은데(예: 파일 또는 데이터베이스에서 스트리밍) 모든 데이터를 한 번에 메모리에 로드하면 편리하고 효율적으로 작업할 수 없다. 일반 함수는 모든 결과를 한 번에 반환하고, 클래스 내에서 자체 이터레이터를 만드는 것은 간단한 경우에 지나치게 번거로울 수 있다.
해결책: yield 메커니즘을 사용하면 데이터의 "게으른" 생성을 조직할 수 있다. 제너레이터 함수는 리스트나 다른 컬렉션을 반환하는 것이 아니라, 필요할 때마다 값을 계산하는 이터레이터인 제너레이터 객체를 반환한다.
코드 예:
# 간단한 제너레이터 def countdown(n): while n > 0: yield n n -= 1 for i in countdown(3): print(i) # 3, 2, 1
주요 특징:
하나의 함수에서 return과 yield를 사용할 수 있습니까?
네, 하지만 제너레이터 내에서 return은 이터레이션을 종료시키고(StopIteration을 발생시킴), yield는 원하는 만큼 사용할 수 있다.
def example(): yield 1 return # StopIteration
완료된 후 제너레이터를 "다시 시작할" 수 없는 이유는 무엇입니까?
이터레이션이 끝난 후(StopIteration) 제너레이터는 다시 시작할 수 없으며, 새로 생성해야 한다.
gen = countdown(2) list(gen) # [2, 1] list(gen) # [] (제너레이터는 이미 소모됨)
제너레이터와 이터레이터의 차이는 무엇입니까?
제너레이터는 이터레이터의 특별한 경우로, iter 및 next 메소드를 가진 객체는 모두 이터레이터이며, 제너레이터는 yield를 통해 함수로 생성된다.
개발자가 분석을 위해 list(fd)를 통해 파일에서 백만 줄을 메모리에 로드하는 함수를 작성했다. 이것은 서버에서 메모리 부족을 초래했다.
장점:
단점:
제너레이터를 이용한 파일의 한 줄씩 읽기 및 yield를 사용한 데이터 온디맨드 분석.
장점:
단점: