본문 바로가기
Python

[Python] Generator Or Iterator 코드 분석 실습

by UnoCode 2020. 6. 27.

다음 코드를 실행해 보고 결과를 분석하는 과정입니다.

 

저의가 풀어얄 할 과정은 3개 입니디.

 

  • lazy evaluation 이란 무엇인가요
  • lazy evaluation을 왜 하는 지와 장점은 무었일까요?
  • list 컴프리헨션과 제너레이터의 차이점은 무었일까요?
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)

 

 

먼저 결과 값 부터 확인 

코드가 가독성이 불변하니(개인적인 기준) 코드를 수정해서  설명드리겠습니다 .

 

1. lazy evaluation 이란?

Lazy Evaluation이란 어떤 코드 조각을 실행할때, 그때그때 값을 평가하지 않고 정말 자기가 원하는 결과겂이 필요한

시점까지 평가를 늦추는 것 입니다.

 

https://itholic.github.io/python-lazy-evaluation/(참고) 이분의 글이 너무나 와닿아서 적었습니다.

 

만약 당신이 스터디룸에서 일하는 직원이다.

이 스터디룸은 스터디 공간뿐 아니라, 간단한 간식도 제공한다.

오후 7시에 10명이 스터디룸을 예약하고, 간식으로 컵라면을 주문해놓았다.

하지만 예약한 손님이 말하길,

 

다들 바빠서 몇 명이 참석할지 모르겠네요, 최악의 경우 아무도 못갈수도 있어요 ㅠㅠ”

당신이 직원이라면 컵라면 10개를 미리 다 끓여 놓겠는가?

아니면 언제든 최대 10명까지 제공할 수 있는 상태로 준비만 해 두겠는가?

 

확실히 10명이 제시간에 온다는 보장이 있다면 전부 미리 물을 부어놓는게 효율적이겠지만,

이 상황은 당연히 후자가 효율적이다.

후자의 경우가 바로 Lazy Evaluation이다.

 

그렇다면 2가지 경우를 코드로 작성해보자

 

미리 10개를 다 끓여 놓는 경우

 

import time

L = range(1, 10)


def print_iter(iter):
    for element in iter:
        print(f"{element} 번째 손님 입장")
        print(f"라면 완성! {element} 번쨰꺼 완성")


def lazy_return(num):
    print(f"라면 끓이는 중 {num} 번째꺼")
    # time.sleep(1)
    return num


print("최대 10명까지 제공할 수 있는 상태로 준비하는게 좋을거 같아!!")
comprehension_list = [lazy_return(i) for i in L]
print_iter(comprehension_list)

 

결과

최대 10명까지 제공할 수 있는 상태로 준비하는 경우

 

import time

L = range(1, 10)


def print_iter(iter):
    for element in iter:
        print(f"{element} 번째 손님 입장")
        print(f"라면 완성! {element} 번쨰꺼 완성")


def lazy_return(num):
    print(f"라면 끓이는 중 {num} 번째꺼")
    # time.sleep(1)
    return num


print("최대 10명까지 제공할 수 있는 상태로 준비하는게 좋을거 같아!!")
comprehension_list = (lazy_return(i) for i in L)
print_iter(comprehension_list)

 

결과 

 

 

 

Why Lazy Evaluation를 사용하는가

이처럼 Lazy Evaluation을 적절히 활용하면,

라면을 미리 다 끓여놓았다가 아무도 오지 않아서 다 버려야하는 상황을 방지할 수 있다.

시간을 들여 연산하고 메모리까지 할당해 놓았는데,

프로그램이 종료될때까지 사용되지 않으면 억울하니까 Lazy Evaluation을 적절히 활용하자.

 

하지만 모든 요소, 혹은 대부분의 요소가 사용될 것이 확실한 상황이라면,

list를 통해 미리 연산을 해 두는 것이 더 효율적이므로 아무 상황에서나 남발하지는 말자.

 

list 컴프리헨션과 제너레이터의 차이점은 무었일까요?

 

제너레이터 함수외에도 제너레이터 표현식(generator expression)이 있는데요. 제너레이터 표현식은 Lazy evaluation을 위해서 사용될 수 있습니다. Lazy evaluation은 말그대로 실행을 지연시킨다는 의미 입니다.

제너레이터 표현식의 문법은 리스트 컴프리헨션 문법과 비슷하지만 대괄호( [ ])가 아닌 괄호를 ( ) 사용하여 만듭니다. 

 

Lazy evaluation을 사용하고 싶다 = 제너레이터 표현식 = comprehension_list = (lazy_return(i) for i in L)

 

그냥 for-in문을 보기 좋게 만들고 싶다 = 컴프리헨션 표현식 = comprehension_list = [lazy_return(i) for i in L]

 

 

표현식에 차이!!

'Python' 카테고리의 다른 글

[Python] import types  (0) 2020.06.28
[Python] Lambda  (0) 2020.06.27
[Python] 이터레이터(Iterator)  (0) 2020.06.27
[Python] 제너레이터(generator)  (0) 2020.06.27
[Python] 패키지 생성 실습  (0) 2020.06.26

댓글