제너레이터(Generator)는 함수 실행을 일시 중단하고 재개할 수 있는 특수 함수다. yield 키워드로 값을 하나씩 생성하며, 전체 컬렉션을 메모리에 올리지 않는 지연 평가(Lazy Evaluation) 를 가능하게 한다.
python
def fibonacci():
a, b = 0, 1
while True: # 무한 시퀀스
yield a # 값 생성 후 일시 중단
a, b = b, a + b
fib = fibonacci()
print(next(fib)) # 0
print(next(fib)) # 1
print(next(fib)) # 1
print(next(fib)) # 2
# 처음 10개만 소비
import itertools
first10 = list(itertools.islice(fibonacci(), 10))
# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
# 대용량 파일 처리 (메모리 효율)
def read_large_file(path):
with open(path) as f:
for line in f:
yield line.strip()
for line in read_large_file("huge.log"):
process(line) # 한 줄씩, 전체 파일을 메모리에 올리지 않음
javascript
function* range(start, end, step=1) {
for (let i = start; i < end; i += step) {
yield i;
}
}
for (const n of range(0, 10, 2)) {
console.log(n); // 0, 2, 4, 6, 8
}
// async 제너레이터
async function* fetchPages(urls) {
for (const url of urls) {
const res = await fetch(url);
yield await res.json(); // 페이지별 지연 처리
}
}
yield from (위임)
python
def chain(*iterables):
for it in iterables:
yield from it # 다른 이터러블에 위임
list(chain([1,2], [3,4], [5])) # [1, 2, 3, 4, 5]
제너레이터 vs 리스트
python
# 리스트: 즉시 평가, 전체 메모리 사용
squares_list = [x**2 for x in range(10**6)] # ~8MB
# 제너레이터: 지연 평가, ~200바이트
squares_gen = (x**2 for x in range(10**6))
관련 개념