#send() 사용 예제
def generator_send():
received_value = 0
while True:
received_value = yield
print("received_value = ",end=""), print(received_value)
yield received_value * 2
gen = generator_send()
next(gen)
print(gen.send(2))
next(gen)
print(gen.send(3))
################################################################3
# 실행 결과
received_value = 2
4
received_value = 3
6
파이썬에서 사용하는 함수 중 특수한 경우라고 볼 수 있는 Generator 함수에 대해서 정리한다.
Generator
- 제네레이터 라고 읽으면 된다.
- 일반적인 함수와 제네레이터 함수의 차이
- 일반 함수는 return을 통해서 작동 결과를 호출 지점으로 반환한다.
- 제네레이터 함수는 yield를 통해서 작동 결과를 호출 지점으로 "산출"한다
- "산출한다."의 의미
- 제네레이터 함수는 반복자 객체를 사용할 수 있으며, __next__를 받기 전에는 작동 이후 지점에 머무르며 대기하고, __next__를 확인하면 다시 함수의 처음로 복귀해서 로직을 수행한다.
- 제네레이터 함수는 send()를 사용해서 도중에 연산에 사용할 값을 전달할 수 있다.
#send() 사용 예제
def generator_send():
received_value = 0
while True:
received_value = yield
print("received_value = ",end=""), print(received_value)
yield received_value * 2
gen = generator_send()
next(gen) #제네레이터 함수 호출
print(gen.send(2)) #값을 send()로 전달
next(gen) #제네레이터 함수 호출
print(gen.send(3)) #값을 send()로 전달
################################################################3
# 실행 결과
received_value = 2
4
received_value = 3
6
제네레이터 표현식 (Generator Expression)
- Lazy evaluation을 사용하기 위한 방법
- Lazy evaluation이란 실행을 지연시킨다는 뜻
- 컴프리헨션 사용과 비슷하지만 그냥 괄호 -() 를 사용해서 표현한다.
- 컴프리헨션은 대괄호-[] 사용
# generator expression 예제
L = [ 1,2,3]
def generate_square_from_list():
result = ( x*x for x in L ) #generator expression 사용
print(result)
return result
def print_iter(iter):
for element in iter:
print(element)
print_iter( generate_square_from_list() )
#################################################################
# 사용 결과
<generator object generate_square_from_list.<locals>.<genexpr> at 0x02C9ABF8>
1
4
9
Assignment
# 이 코드를 분석하자
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)
Lazy evaluation이란?
- 정의 : 어떠한 값이 실제로 쓰일 때까지 그 값의 계산을 뒤로 미루는 것
- 어떤 값이 필요할 때에만 연산을 수행하는 것은 컴퓨팅 자원의 절약에 도움이 된다.
- 전체 연산의 시간도 줄이는 데 도움이 된다.
- 단 코드가 점점 복잡해지고 난해해질 수 있기 때문에 남발하는 것은 금물!
# generator expression을 사용하여 Lazy evaluation 확인 예제
def return_one():
print("return 1")
return 1
print("[let's make one_generator !]")
one_generator = (return_one() for x in range(4))
print("[let's print one_generator !]")
for one in one_generator:
print(one)
#########################################################
# 실행 결과
[let's make one_generator !]
[let's print one_generator !]
return 1
1
return 1
1
return 1
1
return 1
1
리스트 컴프리헨션과 Lazy evaluation의 차이점은?
- 컴프리헨션의 경우는 조건을 대괄호를 사용해서 묶어주지만 Lazy evaluation은 괄호를 사용한다.
# comprehension과 lazy evalution의 비교
test_list = [1, 2, 3]
def print_iter(iter):
for i in iter:
print(i)
def num_return(num):
print("print {}".format(num))
return num
print("Comprehension List=")
comp_list = [num_return(i) for i in test_list]
print_iter(comp_list)
print("Generator Expression")
generate_exp = (num_return(i) for i in test_list)
print_iter(generate_exp)
#######################################################
# 실행 결과
Comprehension List=
print 1
print 2
print 3
1
2
3
Generator Expression
print 1
1
print 2
2
print 3
3
- comprehension의 경우
- num_return을 3회 연속 실행한 후 print_iter을 1회 실행했다.
- 주어진 조건에 맞게 한꺼번에 처리한 후 다음 로직을 수행함
- Lazy evalutaion의 경우
- num_return 1회 실행 후 print_iter을 1회 실행하는 과정을 3회 반복했다.
'wecode > TIL 정리' 카테고리의 다른 글
위코드 Pre Course - 파이썬의 Thread (0) | 2020.07.25 |
---|---|
위코드 Pre Course - 파이썬의 Lambda (0) | 2020.07.25 |
위코드 Pre Course - 파이썬의 Iterator (0) | 2020.07.24 |
위코드 Pre Course - 파이썬의 Comprehension (0) | 2020.07.24 |
위코드 Pre Course - 절대경로와 상대경로 (2) (0) | 2020.07.22 |