제너레이터 (Generator)

2021. 4. 14. 22:16·[Language] - Python

개요


이번 포스트에서는 제너레이터에 대해 알아보고자 한다. 제너레이터는 지연 평가(Lazy Evaluation)을 통해 효율적인 메모리 관리를 가능케 해주는 iterable 객체이다. 제너레이터를 이해하기 위해서는 Eager Evaluation과 Lazy Evaluation의 개념을 알아야 한다.

 


 

Eager Evaluation


def return_func():
    print('return!')
    return 1

li_com = [return_func() for i in range(10)]
print(li_com)

>>
return!
return!
return!
return!
return!
return!
return!
return!
return!
return!
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
  • Eager는 열심인, 열렬한 등의 사전적 의미를 지니고 있다. 즉, 호출되는 즉시 처리되는 형태의 평가 전략을 의미한다.
  • 예를 들면, 위 list comprehension처럼 10번의 retrun_func() 함수가 li_com 리스트가 생성됨과 동시에 바로 호출되고 반환값들이 저장되는 형태이다.
    • 이 과정에서 10번의 모든 함수가 수행되고 결과값들을 리스트에 저장하고 있기 때문에 메모리 점유량이 늘어나게 된다.
    • 만약 극단적으로 데이터양이 많아지거나 iterable의 길이가 길어질수록 OOM(Out Of Memory) 현상이 발생할 수 있다.

 

Lazy Evaluation (Generator)


def init_generator():
    li = [1, 2, 3, 4, 5]
    for i in li:
        yield i

def init_generator():
	li = [1, 2, 3, 4, 5]
    yield from li # for 문 대신 yield from 키워드로 대신할 수 있다.
        
g = init_generator() # <generator object gen at 0x7f89a2f5f970>
  • 제너레이터 인스턴스를 초기화하기 위해서는 return 대신 yield 키워드를 사용한다.
  • yield 키워드 사용 대상은 순회하고 싶은 iterable의 각 원소를 대상으로 한다.
    • 위 예시에서는 init_generator 함수에서 li 라는 리스트를 순회하면서 각 원소를 반환하는 제너레이터 객체를 초기화했다.

 

for i in g:
    print(i)

# 혹은

for i in init_generator():
    print(i)
    
>>
1
2
3
4
5
  • 제너레이터 객체 또한 iterable 이기 때문에 (내부적으로 __iter__() 와 __next__()가 정의됨) 반복문을 통해 순회가 가능하다. 하지만, 이렇게만 보면 일반적인 리스트와 다를게 없어보인다.

 

import time
import random

def init_generator(cnt=5):
    for i in range(cnt):
        yield random.randint(1, 100)
        
g = init_generator()

ret = next(g)
print(f"Timestamp : {time.time()} / Return : {ret}")
time.sleep(1)

ret = next(g)
print(f"Timestamp : {time.time()} / Return : {ret}")
time.sleep(1)

ret = next(g)
print(f"Timestamp : {time.time()} / Return : {ret}")
time.sleep(1)

ret = next(g)
print(f"Timestamp : {time.time()} / Return : {ret}")
time.sleep(1)

ret = next(g)
print(f"Timestamp : {time.time()} / Return : {ret}")

>>
Timestamp : 1748308351.438414 / Return : 32
Timestamp : 1748308352.443619 / Return : 71
Timestamp : 1748308353.4484138 / Return : 10
Timestamp : 1748308354.453526 / Return : 6
Timestamp : 1748308355.4586298 / Return : 24

 

  • Eager Evaluation은 iterable이 생성됨과 동시에 함수가 호출되며 각 원소들을 미리 메모리에 적재하는 과정을 거쳤다.
  • 반면, 제너레이터를 통해 Lazy Evaluation을 수행하면 위 코드의 실행결과처럼 next()에 의해 다음 원소로 넘어가고 나서야 random.randint() 함수가 호출되는 것을 확인할 수 있다.
    • 즉, for 문에서 다음 루프로 넘어갈 때 내부적으로 next()가 호출되는데 이 시점에서 해당되는 인덱스의 원소만 메모리에 적재되고 있는 셈이다.
    • 다시 말해, iterable의 모든 원소를 한번에 메모리에 적재하는 방식이 아닌 각 원소를 순회하는 순간에만 메모리에 적재(Load)했다가 다음 루프로 넘어가면 해당 원소는 메모리에서 다시 해제(Free)시키는 방식으로 동작한다. 이러한 특성은 모든 길이의 원소를 한번에 메모리에 적재시키지 않기 때문에 OOM이 발생할 확률이 낮으며, 실시간성 스트림 데이터를 적재하고 전송하기에 적합하다.

'[Language] - Python' 카테고리의 다른 글

[Tip] 딕셔너리 Fancy하게 다루기  (0) 2021.05.28
[Tip] win32com 모듈을 사용한 엑셀 제어  (0) 2021.04.20
함수형 프로그래밍  (0) 2021.03.25
[Tip] if문 분기와 삼항연산자가 사용하기 싫을 때  (0) 2021.03.24
zip  (0) 2021.03.24
'[Language] - Python' 카테고리의 다른 글
  • [Tip] 딕셔너리 Fancy하게 다루기
  • [Tip] win32com 모듈을 사용한 엑셀 제어
  • 함수형 프로그래밍
  • [Tip] if문 분기와 삼항연산자가 사용하기 싫을 때
Bebsae
Bebsae
  • Bebsae
    뱁새zip
    Bebsae
  • 전체
    오늘
    어제
    • 분류 전체보기 (108)
      • [DevOps] - Kubernetes (5)
      • [DevOps] - AWS (1)
      • [AI] - Machine Learning (19)
      • [AI] - Neural Network (7)
      • [CS] - Network (2)
      • [CS] - Data Structure (3)
      • [CS] - Design Pattern (6)
      • [Language] - Python (15)
      • [Library] - Numpy (7)
        • Quick Start (5)
        • API (2)
      • [Framework] - Django (3)
      • [Framework] - QGIS (6)
      • [Framework] - PyQT (4)
      • [Mathematics] - Linear Alge.. (14)
      • [Mathematics] - Statistical (2)
      • [ETC] - Python (3)
      • [ETC] - C++ (1)
      • [ETC] - Linux (1)
      • 논문 (5)
      • 회고록 (3)
      • 생산성 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • 깃허브
  • 공지사항

  • 인기 글

  • 태그

    decomposition
    MachineLearning
    algebra
    Learning
    numpy
    Convolution
    교차검증
    파이썬
    RNN
    머신러닝
    Python
    선형대수
    디자인패턴
    분해
    QGIS
    DEEPLEARNING
    신경망
    Machine
    Linear
    linearalgebra
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Bebsae
제너레이터 (Generator)
상단으로

티스토리툴바