제너레이터 표현식은 「리스트 컴프리헨션과 같은 문법이지만 ( )를 사용해 제너레이터를 만드는」 표현입니다.
리스트는 모든 요소를 메모리에 미리 만들지만 제너레이터는 하나씩 게으르게 만듭니다.
기본 형식.
squares_list = [x**2 for x in range(10)] — 리스트 [0, 1, 4, 9, ..., 81].
squares_gen = (x**2 for x in range(10)) — 제너레이터.
리스트는 type이 list, 제너레이터는 generator.
for 반복문으로 똑같이 사용 가능합니다.
메모리 차이.
range(1000000) 대상으로 [ ]는 100만 개의 정수가 모두 메모리에 들어감(MB 단위).
( )는 한 번에 한 개씩만 메모리에 — 거의 0에 가까운 메모리.
큰 데이터에서 결정적 차이입니다.
함수 인자로 쓸 때 더 깔끔합니다.
sum([x**2 for x in range(1000000)]) — 리스트를 메모리에 다 만든 뒤 합산.
sum(x**2 for x in range(1000000)) — 제너레이터를 바로 sum에 넘김(괄호 생략 가능).
같은 결과지만 후자가 메모리·속도 모두 효율적입니다.
단점은 「한 번 소비하면 끝」이라는 점입니다.
리스트는 여러 번 순회 가능하지만, 제너레이터는 한 번 for 돌면 다 소비되어 다음 for는 빈 결과를 줍니다.
같은 데이터를 여러 번 순회해야 한다면 리스트가 적합.
한 번만 순회하면서 메모리를 아끼고 싶다면 제너레이터가 답입니다.
한 줄 요약
제너레이터 표현식은 ( )로 만드는 게으른 컴프리헨션으로, 메모리를 거의 안 쓰며 큰 데이터를 처리할 수 있습니다.
한 번만 순회 가능하고 함수 인자로 자주 씁니다.
더 알아볼 것
- 리스트 vs 제너레이터 — 언제 무엇을
- sum(x for x in items)의 괄호 생략
- itertools와의 결합