당신의 친절한 이웃, 코딩맨

#19 Python - lazy evaluation, list comprehension 비교 본문

Today I Learn (TIL)

#19 Python - lazy evaluation, list comprehension 비교

이웃집 친구 2020. 6. 29. 16:32
반응형
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] #[1,2,3]
print_iter(comprehension_list)

print("generator_exp=")
generator_exp = (lazy_return(i) for i in L) #[]를 ()로 바꿔줌.
print_iter(generator_exp)

 

comprehension_list=
sleep 1s
sleep 1s
sleep 1s
1
2
3

generator_exp=
sleep 1s
1
sleep 1s
2
sleep 1s
3

 

List comprehension으로 호출했을 때:

[lazy_return(i) for i in L] 여기서 lazy_return 함수를 한 번에 메모리 할당까지 하고, 호출까지 다 완료한다.

그래서 출력된 화면에 'sleep 1s' 이 세 번 반복하고 print_iter가 실행된다. (123이 호출되어있다.)

이 경우는, lazy return 함수는 한 번만 호출되었지만, 모든 리스트가 다 생성이되었기때문에, sleep 1s가 세번 출력 된것이다. 다시 말해, 사실 print_iter함수는 1을 출력하기 위해, sleep 1s가 한번만 필요하지만, list comprehension으로 표현했기 때문에, lazy_return 함수가 앞으로 사용될지 안될지도 모르는 상태로 3번 다 호출해서 return값을 print_iter함수에게 전달했다.

 

Generator expression으로 호출했을 때:

(lazy_return(i) for i in L) 이렇게 제너레이터로 호출하면 lazy_return 함수는 실제로 generator_exp가 필요할 때만 호출되었다. 그 후로도 계속 실제로 필요할 때'만' lazy_return함수가 값을 return 해주었기 때문에 sleep 1s와 1 번갈아 가면서 출력된 것을 결괏값으로 확인해 볼 수 있다.

 

=> 이런 결과로 미루어 볼 때, lazy evaluation은 필요할 때만 호출되기 때문에, 미래에 사용되지 않을 수 있는 불필요한 메모리, 시간을 절약할 수 있다는 장점이 있다. 하지만 리스트의 대부분이 사용될 것으로 예상되면, 미리 전부 만들어 놓고 사용하는 게 효율적이므로 아무 상황에서 남발해서는 안된다.

 

 

 

Comments