Post

[Python] Generator 표현식에 대해서

[Python] Generator 표현식에 대해서

🟣 Generator란?

‘Fluent Python’에서 강조하는 개념으로 복잡한 개념은 아니지만 iterator의 개념은 python에서 굉장히 많이 사용되는 문법이지만 제대로 배우거나 정리한 적은 없어서 이번 기회에 살짝 정리해보았다.

🟡 Generator? Iterator?

| 항목 | Generator | Iterator | | —————————— | ————————————— | ——————————————— | | ✅ 정의 | 값을 lazy하게 생성하는 함수 or 표현식 | 값을 순차적으로 반환하는 객체 | | ✅ __iter__, __next__ 구현 여부 | 둘 다 구현되어 있음 (자동으로) | 명시적으로 구현하거나 iter()로 생성 | | ✅ 사용 목적 | 값을 하나씩 생성해서 순회할 수 있게 함 | 값을 순차적으로 꺼낼 수 있는 인터페이스 제공 | | ✅ 생성 방식 | yield or generator expression 사용 | class 또는 iter()로 생성 |

  • generator랑 iterator는 굉장히 비슷한 개념이고, 실제로 generator는 iterator의 한 종류라고 볼 수 있음
  • 근데 둘 사이에는 약간의 구조적 차이와 생성 방식의 차이가 있음
    • 모든 generator는 iterator다 (iter(), next() 있음)

    • 하지만 모든 iterator가 generator는 아니다 → 예: iter([1,2,3])은 iterator지만 generator는 아님

🟡 Generator

1
(x*x for x in range(1000))
  • 하나씩 값을 lazy하게 계산해서 반환
  • 리스트를 만들지 않고, 한 번에 하나씩만 처리
  • 메모리 절약에 유리

🟡 List comprehension

1
[x*x for x in range(1000)]
  • 전체 결과를 한꺼번에 메모리에 저장함 (리스트 생성)
  • 결과가 바로 리스트로 materialize됨
  • 빠르지만 메모리를 많이 쓸 수 있음

🟡 예제 비교

1
2
3
4
5
6
7
8
9
10
11
import sys

lst = [x*x for x in range(1000000)]      # 리스트 컴프리헨션
gen = (x*x for x in range(1000000))      # 제너레이터 표현식

print(sys.getsizeof(lst))  # ❗ # 리스트는 8697464(약 8MB)
print(sys.getsizeof(gen))  # ❗ 제너레이터 112
"""
8697464   # 리스트는 약 8MB
112       # 제너레이터는 고정된 메모리 (next 포인터만 있음)
"""

🟣 마무리

generator는 iterator를 더 쉽게, 간단하게 만드는 방법이다. 둘 다 lazy하게 값을 하나씩 처리하며, for, next(), sum() 등에서 동일하게 쓸 수 있다.

This post is licensed under CC BY 4.0 by the author.