Python 제너레이터 표현식

코딩Python
읽는데 14분 소요
처음 쓰여진 날: 2026-04-07
마지막 수정일: 2026-05-22
조회수:

요약

Python의 제너레이터 표현식과 sum/any/all/join 활용법, next() 동작과 게으른 평가까지 정리합니다. 정보처리기사 실기에 자주 등장하는 한 줄 표현식 문법입니다.

제너레이터 표현식 핵심 정리

개념형식예시
제너레이터 표현식(식 for 변수 in 반복)(x * 2 for x in lst)
조건부 제너레이터(식 for 변수 in 반복 if 조건)(x for x in lst if x > 0)
next로 값 꺼내기next(gen)호출 시점에 표현식 1회 평가
게으른 평가요청 시점에 계산큰 데이터 일부만 쓸 때 유리
sum/any/all과 결합sum(식 for 변수 in 반복)sum(x for x in lst)

제너레이터 표현식 기초

제너레이터 표현식(generator expression)리스트 컴프리헨션의 대괄호 []를 소괄호 ()로 바꾼 형태입니다.

제너레이터 표현식의 형식

python
코드 하이라이팅 중...

리스트 컴프리헨션과 모양이 거의 같지만, 결과로 만들어지는 것이 리스트가 아니라 제너레이터 객체라는 점이 다릅니다.

python
코드 하이라이팅 중...

리스트 컴프리헨션과의 차이

항목리스트 컴프리헨션 [...]제너레이터 표현식 (...)
결과 자료형listgenerator
메모리 사용모든 결과를 한꺼번에 저장꺼낼 때마다 하나씩 계산
직접 출력값이 그대로 보임<generator object ...>로 보임
for문으로 순회가능 (여러 번 가능)가능 (한 번 소비 후 끝)
sum(), any(), all() 인자가능가능 (괄호 생략 가능)

리스트는 결과 5개를 메모리에 한꺼번에 만들어 보관하지만, 제너레이터는 for문 등으로 하나씩 꺼낼 때마다 그때그때 계산해서 내어줍니다. 그래서 메모리를 적게 쓰고, 첫 번째 값이 빨리 필요한 상황에 유리합니다.

딕셔너리·집합 컴프리헨션까지 포함한 4종 비교는 컴프리헨션 통합 정리 페이지에서 한 자리에 정리합니다.

직접 순회해 보기

제너레이터 객체는 for문이나 next() 함수로 값을 꺼낼 수 있습니다.

python
코드 하이라이팅 중...

next 함수로 값 꺼내기

next()는 제너레이터에서 다음 값을 하나 꺼내는 내장 함수입니다. 한 번 호출할 때마다 표현식을 한 번 평가해 그 결과를 돌려줍니다.

python
코드 하이라이팅 중...
next() 호출 시점마다 표현식이 한 번씩 평가되어 값을 반환하는 시간 흐름. 값이 소진된 뒤 호출하면 StopIteration 예외 발생
next() 호출 순간에 표현식이 한 번씩 평가됩니다 — T4처럼 값이 소진된 뒤 호출하면 StopIteration 예외 발생

중요한 두 가지 동작이 있습니다.

  • 계산 시점이 호출 시점과 같습니다. 제너레이터를 만드는 줄에서는 아무것도 계산되지 않고, next()를 호출하는 그 순간에 비로소 표현식이 평가됩니다. 이 성질이 게으른 평가의 핵심입니다.
  • 값이 모두 소진된 뒤에 next()를 한 번 더 호출하면 StopIteration 예외1가 발생합니다. 위 예시는 값을 3번 꺼냈으므로 한 번 더 호출하면 다음과 같이 됩니다.
python
코드 하이라이팅 중...

실제로 실행하면 다음과 같은 오류 메시지가 출력됩니다.

text
코드 하이라이팅 중...

for문과 next()의 관계

for문은 내부적으로 next()를 반복 호출하다가 StopIteration 예외가 발생하면 자동으로 반복을 멈춥니다. 그래서 다음 두 코드는 동일하게 동작합니다.

python
코드 하이라이팅 중...

for문을 쓰면 StopIteration 처리를 직접 신경 쓸 필요가 없어 편하지만, "값이 한 번에 하나씩 만들어지는 동작"은 next()를 직접 써 봤을 때 가장 잘 보입니다.


게으른 평가 호기심

제너레이터의 가장 큰 특징은 게으른 평가(lazy evaluation)입니다. 값을 미리 다 만들어 두지 않고, 실제로 요청받는 시점에 표현식을 평가하고 결과를 반환합니다. 리스트 컴프리헨션은 반대로 만드는 즉시 모든 결과를 계산해서 메모리에 보관하는 즉시 평가(eager evaluation)입니다.

리스트 컴프리헨션(즉시 평가)은 결과 전체를 메모리에 보관하고, 제너레이터 표현식(게으른 평가)은 표현식만 보관하다 요청 시점에 1개씩 계산하는 비교 다이어그램
리스트는 만들 때 결과 전체를 메모리에, 제너레이터는 표현식만 보관하고 next() 요청 시점에 1개씩 계산합니다

평가 시점 비교

표현식 안에서 print를 호출해 보면 평가 시점이 한눈에 드러납니다.

python
코드 하이라이팅 중...

코드에서 f"square({x}) 호출됨"f-string입니다. 문자열 앞에 f를 붙이고 {} 안에 변수를 넣으면 실행 시점에 값이 끼워 넣어집니다.

리스트는 만드는 순간 square(1), square(2), square(3)이 모두 호출됩니다. 제너레이터는 만드는 줄에서는 아무 호출도 일어나지 않고, next()로 값을 요청할 때 비로소 square(1)이 호출됩니다.

메모리 효율성

게으른 평가의 가장 큰 실용적 장점은 메모리 효율성입니다. 실무에서는 1억 개처럼 매우 많은 값을 다룰 때, 그 중 일부만 필요한 경우가 많습니다. 리스트라면 필요 없는 나머지까지 모두 메모리에 올려야 하지만, 제너레이터는 필요한 만큼만 만들어 씁니다.

Python에서는 큰 숫자를 100_000_000처럼 언더바로 끊어 쓸 수 있어 가독성을 높입니다. 100_000_000100000000(1억)과 완전히 같습니다.

python
코드 하이라이팅 중...

코드에서 _는 "값을 받았지만 쓰지 않는다"는 뜻의 관행적 변수명입니다. for _ in range(10)은 "10번 반복하되 반복 변수는 필요 없다"는 의미입니다.

리스트 방식은 1억 개의 결과를 모두 만들어 두고 그중 10개만 사용합니다. 제너레이터 방식은 next()를 10번만 호출했으므로 x * 2도 10번만 평가됩니다. 나머지 99,999,990개는 계산조차 안 됩니다.

앞서 본 표(L67)는 자료형·출력·순회 가능 여부를 비교했고, 여기서는 평가 시점과 메모리 관점으로 다시 정리합니다.

항목리스트 컴프리헨션제너레이터 표현식
평가 시점만드는 즉시 (eager)요청 시점마다 (lazy)
메모리 사용량결과 전체 크기한 번에 1개
큰 데이터에서 일부만 쓸 때비효율효율
같은 값을 여러 번 쓸 때효율 (재사용)매번 새로 생성 필요

sum, any, all과 함께 쓰기 심화

제너레이터 표현식이 가장 자주 쓰이는 곳은 sum(), any(), all() 같은 집계 함수의 인자입니다. 이런 함수들은 이터러블2을 받아 한 번씩 순회하면서 값을 모으는 동작을 하므로, 제너레이터와 잘 맞습니다.

sum/any/all 함수가 제너레이터에서 한 값씩 next로 받아 즉시 처리하는 비교 다이어그램. sum은 끝까지 누적, any는 첫 True에서 단락, all은 첫 False에서 단락
sum은 끝까지 누적, any는 첫 True에서 단락, all은 첫 False에서 단락 — 제너레이터에서 한 값씩 받아 즉시 처리

sum과 결합

sum(이터러블)은 이터러블의 모든 값을 더해 결과를 돌려줍니다.

python
코드 하이라이팅 중...

함수 호출의 괄호 안에 제너레이터 표현식이 들어갈 때는 제너레이터 표현식의 괄호를 생략할 수 있습니다. sum(x * 2 for x in nums)sum((x * 2 for x in nums))와 같습니다.

join과 결합 — 조건에 맞는 값만 문자열로 합치기

'구분자'.join(이터러블)은 리스트나 문자열 같은 이터러블의 요소들을 구분자로 이어 붙여 하나의 문자열을 만듭니다. join()의 인자 자리에도 제너레이터 표현식을 바로 넣을 수 있습니다.

python
코드 하이라이팅 중...

숫자 리스트를 문자열로 합칠 때도 str()로 변환하는 제너레이터 표현식을 바로 넘기면 깔끔합니다.

python
코드 하이라이팅 중...
패턴의미결과
''.join(c for c in y)모든 문자를 그대로 이어 붙임"Hello"
''.join(c for c in y if 조건)조건에 맞는 문자만 이어 붙임조건 만족 문자 집합
','.join(str(n) for n in nums)숫자 리스트를 문자열로 연결"1,2,3"

조건부 제너레이터 표현식

리스트 컴프리헨션과 마찬가지로, 제너레이터 표현식에도 if 조건을 붙여 원하는 값만 골라낼 수 있습니다.

python
코드 하이라이팅 중...
python
코드 하이라이팅 중...
조건부 제너레이터 표현식: if 필터를 통과한 값(2, 4)만 sum으로 흘러가는 3단계 흐름
if 조건을 통과한 값(2, 4)만 제너레이터에서 yield되어 sum에 누적됩니다 (1, 3, 5는 탈락)

조건을 통과한 값은 제너레이터가 하나씩 내어 보냅니다(yield). yield는 "값을 하나 꺼내 준다"는 뜻으로, next()를 호출할 때마다 다음 조건 통과 값을 하나씩 전달합니다.

이 표현식을 일반 for문으로 풀어 쓰면 다음과 같습니다.

python
코드 하이라이팅 중...

재귀 함수와 결합한 시험 패턴

정보처리기사 실기에서는 재귀 함수와 제너레이터 표현식이 함께 등장하는 패턴이 출제된 적이 있습니다. 트리 구조의 자식 노드들을 모두 더할 때 다음과 같은 형태로 자주 쓰입니다.

python
코드 하이라이팅 중...
트리 노드의 자식들에 calc를 재귀 호출하고 그 결과를 sum이 누적하는 흐름. 한 줄 sum + 제너레이터가 일반 for문 누적과 동일하게 동작
자식들에 calc를 재귀 호출한 결과를 sum이 next로 한 값씩 받아 누적합니다 — 한 줄 식이지만 일반 for문 누적과 동일

이는 다음 일반 for문과 같습니다.

python
코드 하이라이팅 중...

sum() 안에 제너레이터 표현식을 넣어 한 줄로 줄여 쓴 형태입니다. 한 줄짜리 식이지만 동작은 위 일반 for문과 똑같다는 점을 외워두면 시험에서 분해하기 쉽습니다.

any와 all

any()all()도 같은 패턴으로 쓸 수 있습니다. 이 두 함수는 단락 평가(short-circuit)를 합니다. any()True인 값을 하나 찾는 순간, all()False인 값을 하나 찾는 순간 즉시 순회를 멈춥니다. 나머지 값은 평가하지 않으므로, 제너레이터와 결합하면 불필요한 계산을 줄일 수 있습니다.

python
코드 하이라이팅 중...

정보처리기사 실기 기출 문제


Footnotes

  1. 예외(exception): 코드 실행 중 발생하는 오류입니다. 직접 처리(try/except)하지 않으면 프로그램이 즉시 중단됩니다. StopIteration은 더 꺼낼 값이 없는 이터러블에서 next()를 호출할 때 발생하는 예외입니다.

  2. 이터러블(iterable): 리스트, 튜플, 문자열, 제너레이터처럼 여러 값을 차례대로 꺼낼 수 있는 대상을 통틀어 이르는 말입니다. for ... in ... 구문에 넣을 수 있는 모든 것이 이터러블입니다.


Python 제너레이터 표현식 | 정처기 감자