"게으른 값계산"이라는 의미의 이 기법은 필요할 때까지 계산을 늦추겠다는 뜻이다.
이와 반대되는 개념이 "조금한 값계산" 또는 "엄격한 값계산"으로 우리가 일반적으로 알고 있는 프로그래밍 동작 기법이다. 함수를 호출하면 로직 실행 및 결과를 받는 절차가 일반적이지만 성능을 위해 함수를 호출할 준비만 해놓고 사용자가 원하는 시점에 실행이 되도록 하고 싶은 경우가 있을 수 있다. 이 때 Lazy Evalution을 고려할 수 있다.
아래의 코드를 보자.
import time
L = [1,2,3]
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)
위 code는 메시지와 함께 1초 sleep하는 함수를 구성원으로 하는 iterator를 만들고 이를 순차적으로 호출하는 내용이다.
comprehension_list는 list comprehension 방식으로 list L의 구성원만큼 lazy_return 함수의 결과를, generator_exp는 generator expression을 통해 list L의 구성원만큼 lazy_return 함수를 호출하는 generator를 담고 있다.
각 iterator를 print_iter() 에 인자로 실행하면 결과는 아래와 같다.
comprehension_list=
sleep 1s
sleep 1s
sleep 1s
1
2
3
generator_exp=
sleep 1s
1
sleep 1s
2
sleep 1s
3
Process finished with exit code 0
둘의 실행결과가 틀리다.
list comprehension은 생성과정에서 함수가 호출이되어 로직 실행 및 결과를 return, return된 값이 iterator에 담겨진다. 3번의 함수가 호출되므로 총 3회의 메시지 출력 및 1초 sleep 이 발생하고 최종적으로 다음의 iterator를 순차적으로 출력하게 되는 것이다.
comprehension_list = [1, 2, 3]
generator expression 과정에서는 함수가 실행되지 않고 generator로 만들어져 iterator에 들어가며 iterator의 각 element 접근시에 함수가 실행 및 결과를 return 한다.
comprehension_list = {generator}