제너레이터는 지연 평가(lazy evaluation) 구현체이다.
파이썬에서 모든 lazy evalution은 이터레이터(iterator)라고 불린다. 이러한 이터레이터 중에서 특정 방식을 통해서 생성한 이터레이터를 제너레이터라고 부른다. |
즉, 객체의 값을 미리 생성해서 저장해 두지 않고 해당 객체를 사용할 때 값을 계산해서 반환해준다.
제너레이터는 소괄호()를 이용한 컴프리헨션으로 생성할 수 있다.
num = (x for x in range(10)) print(num) >><generator object <genexpr> at 0x00000214166F4AC8>
위의 설명처럼 객체를 사용할 때 값을 계산해주므로 for문으로 제너레이터를 사용해보면
num = (x for x in range(10)) for x in num: print(x, end=' ') >>0 1 2 3 4 5 6 7 8 9
next함수로도 제너레이터의 사용이 가능하다. next함수는 제너레이터의 다음 값을 반환해준다.
num = (x for x in range(3)) print(next(num)) print(next(num)) print(next(num)) >>0 >>1 >>2
정해진 범위를 벗어나면 StopIteration 에러가 발생한다.
num = (x for x in range(3)) print(next(num)) print(next(num)) print(next(num)) print(next(num)) >>0 1 2 Traceback (most recent call last): File "..............................", line 5, in <module> print(next(num)) StopIteration
제너레이터는 다른 이터레이터(iterator)와 달리 값을 계산해서 반환해주고 나면 값을 소비하고 더 이상 기억하지 않는다.
(재사용이 불가능하다.)
num = (x for x in range(10)) for x in num: print(x, end=' ') for x in num: #두 번째 for문에서는 아무것도 출력이 되지않는다. print(x, end=' ') >>0 1 2 3 4 5 6 7 8 9
yield를 이용한 제너레이터 생성
def문을 이용한 함수 내부에 yield 키워드를 사용하여 제너레이터의 생성이 가능하다.
아래와 같이 값을 단순 지정해줄 수도 있고
def gen(): yield 0 yield 1 yield 2 x=gen() #제너레이터 x 생성 for i in x: print(i) >>0 1 2
보통 함수와 같이 내부에 for문과 if문을 사용할 수도 있다.
def gen(): for i in range(3): yield i x=gen() for i in x: print(i) >>0 1 2
파이썬은 함수 내부에 yield 키워드가 하나라도 존재하면 해당 함수를 generator로 인식한다. |
아래와 같이 함수에 인자를 받으면 더 다양한 제너레이터를 생성할 수 있다.
또한 반복문을 이용하여 매번 다른 값을 생성하여 반환해준다면 재사용도 가능할 것이다.
import random def broken_dice(n): #1~6까지의 주사위 값중 n을 제외하고 리턴 while True: number = random.randint(1, 6) # 1~6까지 정수 중 랜덤하게 숫자를 뽑는다. if number != n: # 랜덤하게 뽑은 숫자, n이 아니라면 리턴 yield number dice=broken_dice(5) for i in range(6): print(next(dice)) >>2 2 2 1 1 4
'Python' 카테고리의 다른 글
Python - 컴프리헨션(Comprehension) (0) | 2020.08.25 |
---|---|
Python - 람다함수(익명함수) (0) | 2020.08.24 |
Python - 전역 변수, 지역 변수 (0) | 2020.08.23 |
Python - mutable객체, immutable객체 (0) | 2020.08.22 |
Python - 빠른 입력 (0) | 2020.08.17 |