yield 키워드란 무엇인가?
'yield' 키워드는 제너레이터(generator)에서 사용됩니다. 그 동작 방식을 이해하려면 먼저 이터러블(iterable)이 무엇인지 알아야 합니다.
Python에서 리스트(list), 파일(file), 문자열(string) 등의 객체를 이터러블이라고 부릅니다. 즉, for ... in 구문으로 순회할 수 있는 모든 객체가 이터러블에 해당합니다. 이터레이터(iterator) 객체 역시 이터러블의 일종이지만, 단 한 번만 순회할 수 있다는 점이 다릅니다. 이터레이터 객체는 iter() 함수를 통해 모든 이터러블로부터 얻을 수 있으며, next() 메서드를 사용해 순회를 진행합니다.
>>> L1 = [1,2,3,4]
>>> I1 = iter(L1)
>>> while True:
try:
print (next(I1))
except StopIteration:
sys.exit()
제너레이터의 작동 원리
제너레이터는 겉모습이 일반 함수와 매우 비슷하지만, yield 키워드를 통해 이터레이터의 항목들을 하나씩 차례로 산출(yield)한다는 점에서 큰 차이가 있습니다.
제너레이터 함수를 호출하면, 함수 본문이 실행되기도 전에 이터레이터 객체가 즉시 반환됩니다. next() 메서드가 처음 호출되는 순간에야 함수가 실제로 실행되기 시작하고, yield 문에 도달하면 해당 값을 반환한 뒤 실행을 일시 정지합니다. 중요한 점은 yield가 마지막 실행 위치를 기억한다는 것이며, 두 번째 next() 호출 시에는 중단된 지점, 즉 이전 값의 바로 다음부터 실행을 이어갑니다.
피보나치 수열 생성 예제
다음 예제는 피보나치(Fibonacci) 수열의 숫자들을 담은 이터레이터를 생성합니다. 제너레이터 함수 fibo()가 호출될 때마다 피보나치 수열의 다음 항목이 하나씩 순서대로 산출됩니다.
import sys
def fibo(n):
a,b=0,1
while True:
if a>n : return
yield a
a, b = b, a+b
f = fibo(20)
while True:
try:
print (next(f))
except StopIteration:
sys.exit()
핵심 포인트 정리
- yield는 함수를 일시 정지시키고 값을 반환하며, 다음 호출 시 중단된 지점부터 실행을 재개합니다.
- 제너레이터 함수는 호출 즉시 실행되지 않고, 이터레이터 객체만 반환합니다.
- 모든 항목을 메모리에 미리 담아두는 리스트와 달리, 제너레이터는 필요할 때 값을 하나씩 생성하므로 대용량 데이터 처리에 효율적입니다.
- 순회가 끝나면 StopIteration 예외가 발생하여 반복이 종료됩니다.