728x90


제네레이터 함수(Generators function)

 

'제네레이터 함수' 란 '제네레이터' 를 만들기 위한 함수의 정의를 의미 하며,
'제네레이터' 란 iterator 객체의 한 종류로 next 함수를 사용하면 생성된 제네레이터 객체에서 값을 하나씩 꺼낼 수 있다.(여기까지는 iterator의 기능) 특이점은 제네레이터 함수 내부에는 yield가 있다는 것에 있다. next 함수가 호출 될 때마다 yield 문을 만날 때까지 실행을 이어간다. yield는 return의 역할을 하고 있으며 브레이크와 유사한 기능을 한다.
iterator 객체의 특징을 그대로 갖고 있기 때문에 마지막 yield까지 실행되었는데 next 함수를 호출한다면 StoprIteration 예외가 발생한다.
제네레이터 객체는 반환할 값들을 미리 만들어서 저장해 두지 않기 때문에 메모리를 효율적으로 사용한다는 장점이 있다.
생성되는 값들을 순서대로 하나씩 가져다 쓰면 되는 상황(ex) for문  등)에서는 제네레이터를 사용해 코드를 만드는 것이 효율적이다.

* map 함수와 filter 함수가 반환 하는 값은 iterator 객체이자 '제네레이터' 객체
* yield from obj을 사용하면 for루프와 완전히 동일한 기능을 하는 간결한 코드를 작성할 수 있다. (obj에 있는 값들을 하나씩 yield)

# 메모리 체크
import sys


def gen(s):
    for i in s:
        yield i ** 2


st = gen(list(range(1, 10)))
for i in st:
    print(i, end=" ") # 1 4 9 16 25 36 49 64 81 

print(sys.getsizeof(st)) # 112
# 각 구문 비교

# 1
def for_return(n):
    blank_list = []
    for i in n:
        blank_list.append(i)
    return blank_list


# 2
def for_yield(n):
    for i in n:
        yield i


# 3
def yield_from(n):
    yield from n


li = list(range(1, 11))
# 1
print(for_return(li))  # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 2
gen_fy = for_yield(li)
print(next(gen_fy))  # 1
# 3
gen_yf = yield_from(li)
print(next(gen_yf))  # 1

제네레이터 표현식(Generators expression)

 

'제네레이터 표현식' 이란 '제네레이터' 를 만들기 위한 을 의미하며, 제네레이터 함수와 마찬가지로 제네레이터 객체를 생성하는 방법이다. 이렇게 만들어진 제네레이터는 next 함수가 호출 될 때마다 값을 하나씩 반환한다.
제네레이터 표현식은 리스트 컴프리헨션의 [ . . . ]가 ( . . . )로 바뀌 었을 뿐 문법 구성은 거의 똑같다. 따라서 제네레이터 표현식은 간결함과 메모리 효율성을 모두 잡을 수 있다. 

# 1 제네레이터 함수
def g_func():
    for i in range(1, 10):
        yield 2*i


gen_func = g_func()  # 제네레이터 객체 생성
print(next(gen_func))  # 2

# 2 제네레이터 표현식
gen_exp = (2*i for i in range(1, 10))
print(next(gen_exp))  # 2

 

 

728x90

+ Recent posts