제너레이터는 지연 평가(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

 

 

출처:https://wikidocs.net/22802

'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

+ Recent posts