python : generators

gaya309·2021년 5월 24일
0

python

목록 보기
5/5
post-thumbnail

다른 언어들을 배우면서 iterator 개념은 많이 보고 사용해봤지만, python을 하며 generator에 대해서는 처음들었다. iterator와 비슷한듯 달라서 이걸 도대체 왜쓰는거지..??😑라는 의문이 들었는데, 공부하다보니 오..이런것도 있구나 싶었다👀
이번에 generator에 대해 이해한 내용을 정리해 보고자 한다!! 🙌

generator

제너레이터는 반복자(iterator)와 같은 루프의 작용을 컨트롤하기 위해 쓰여지는 특별한 함수 또는 루틴이다.( 이터레이터를 생성해주는 함수 )

dir 함수를 사용하여 generator를 출력 해보면

['__class__', '__del__', '__delattr__', '__dir__', '__doc__', '__eq__', 
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', 
'__init_subclass__', '__iter__', '__le__', '__lt__', '__name__', '__ne__', 
'__new__', '__next__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'gi_code', 
'gi_frame','gi_running', 'gi_yieldfrom', 'send', 'throw']

__next__, __iter__함수 둘다 가지고 있는 것을 확인 할 수 있다. iterator와 다르게 바로 __next__함수를 실행 할 수 있다.

yield

일반 함수와 다르게 generator는 return 값 대신 yield를 사용하여 값을 산출한다.

일반 함수

def sum(a, b):
	return a+b

➡️ return 후 함수 종료

generator

def sum(a, b):
	yield a+b

➡️ yield를 만나면 호출 부분으로 값을 반환해준 뒤, 함수 상태 유지

다음 next()를 할 경우 함수 처음부터가 아닌 yield 이후부터 다시 실행된다.

send()

send() 사용 시 generator 실행 중간에 값을 보낼 수 있다.

def sum(a):
    b = yield
    yield a + b
 

s = sum(1)
next(s)
print(s.send(2))

generator expression

generator를 간단하게 표현 하는 방법
list comprehension과 사용법이 비슷하다. [] 대신 () 사용

def print_iter(iter):
    for element in iter:
        print(f"e={element}")


L = [1, 2, 3]
result = (x for x in L)
print_iter(result)

generator expression vs list comprehension

import time

def print_iter(iter):
    for element in iter:
        print(element)

def lazy_return(num):
    print("sleep 1s")
    time.sleep(1)
    return num

print("comprehension_list=")
comprehension_list = [ lazy_return(i) for i in L ]
print_iter(comprehension_list)

print("generator_exp=")
generator_exp = ( lazy_return(i) for i in L )
print_iter(generator_exp)
  • list comprehension과 다르게 한번에 모든 값을 반환하는 것이 아니라 한번 호출 시 하나의 값을 반환한다.
    ➡️ 한번에 모든 값을 가져오는 것이 아니기 때문에 필요할때까지 다음 실행을 지연 시킬 수 있다. (lazy Evaluation이라고 부르는 이유)
    ➡️ list comprehension은 리스트 생성 시 데이터를 리스트의 크기만큼 메모리에 적재하지만, generator expression은 generator 생성 시 값을 메모리에 전부 할당하진 않는다.(규칙 등, 상태값은 담고 있지만 전체 값을 메모리에 담진 않는다.)

결론

generator 사용

  • 메모리 부담을 줄일 수 있다. (데이터의 양이 커질수록 더 효과적이다.)
  • 연산이 필요할 때 실행 할 수 있어, 수행기간이 긴 연산들을 지연 시킬 수 있다.
profile
🎓의지적인 삶을 살자!😊

0개의 댓글