본문 바로가기
카테고리 없음

리스트 컴프리헨션과 제너레이터

by BOOST YOUR INFORMATION 2026. 7. 18.

리스트 컴프리헨션과 제너레이터

1. 기본 개요

파이썬 공식 문서(Python 3 Tutorial, "5.1.4. List Comprehensions")에 따르면, 리스트 컴프리헨션은 기존 반복 가능한 객체(iterable)를 바탕으로 새로운 리스트를 간결하게 만들 수 있는 문법입니다. 일반적인 for 반복문으로 리스트를 채우는 코드를 한 줄로 압축할 수 있습니다.

squares = [x**2 for x in range(10)]

이는 다음 코드와 동일한 결과를 만들지만 더 간결합니다.

squares = []
for x in range(10):
    squares.append(x**2)

제너레이터(generator)는 이터레이터(iterator)를 만드는 또 다른 방법으로, 파이썬 공식 튜토리얼("9.10. Generators")과 공식 HOWTO 문서("Functional Programming HOWTO")에서 설명하듯 yield 문을 사용하는 함수, 또는 리스트 컴프리헨션과 비슷한 문법에 대괄호 대신 소괄호를 쓰는 제너레이터 표현식(generator expression)으로 만들 수 있습니다.

def square_generator(n):
    for x in range(n):
        yield x**2

squares_gen = (x**2 for x in range(10))

제너레이터의 핵심은 리스트처럼 모든 값을 한꺼번에 메모리에 저장하지 않고, 값이 필요할 때마다 하나씩 계산해서 넘겨준다는 점입니다.

2. 기능과 스펙

리스트 컴프리헨션의 문법 요소

  • 기본형: [표현식 for 항목 in 반복가능객체]
  • 조건 필터: [표현식 for 항목 in 반복가능객체 if 조건]
  • 중첩 반복: [표현식 for x in A for y in B]로 이중 for문 표현 가능
  • 리스트뿐 아니라 딕셔너리 컴프리헨션({k: v for ...}), 셋 컴프리헨션({x for ...})도 동일한 방식으로 지원

제너레이터의 특징

  • yield가 포함된 함수는 호출해도 즉시 실행되지 않고, 제너레이터 객체를 반환한다
  • next()를 호출하거나 for 문으로 순회할 때마다 yield 지점까지 실행되고, 그 지점에서 실행이 일시 정지된 채로 값을 넘겨준다
  • 함수 내부의 지역 변수와 실행 상태는 다음 next() 호출 때까지 그대로 유지된다
  • 제너레이터는 한 번 소진(exhausted)되면 다시 처음부터 순회할 수 없고, 새로 생성해야 한다

파이썬 공식 문서는 제너레이터가 이터레이터 프로토콜(__iter__, __next__)을 자동으로 구현해주기 때문에, 사용자가 직접 이터레이터 클래스를 만드는 것보다 훨씬 적은 코드로 동일한 기능을 구현할 수 있다고 설명합니다.

3. 장단점

장점

  • 리스트 컴프리헨션은 단순 반복+조건 필터링 작업을 짧고 읽기 쉬운 코드로 표현할 수 있다
  • 제너레이터는 전체 데이터를 한꺼번에 메모리에 올리지 않으므로, 대용량 데이터나 무한히 이어지는 데이터 스트림을 다룰 때 메모리 효율이 크게 높아진다
  • 제너레이터는 필요한 시점에만 값을 계산하는 지연 평가(lazy evaluation) 방식이라, 앞부분 몇 개 값만 필요한 경우 불필요한 연산을 줄일 수 있다

단점

  • 리스트 컴프리헨션 안에 조건문과 중첩 반복문을 과도하게 넣으면 오히려 일반 for 문보다 읽기 어려워질 수 있다
  • 제너레이터는 한 번 순회하면 소진되어 재사용이 불가능하므로, 같은 데이터를 여러 번 순회해야 하는 경우에는 부적합할 수 있다
  • 제너레이터의 값은 len()으로 개수를 미리 알 수 없고, 인덱싱(gen[0])도 지원하지 않아 리스트와 동일하게 다루려는 초보자가 혼란을 겪기 쉽다

개인적 견해 및 비판: 리스트 컴프리헨션은 파이썬다운(Pythonic) 코드의 대표적인 예로 자주 소개되지만, "짧게 쓰는 것 자체"가 목적이 되어 조건절과 중첩 for문을 무리하게 한 줄에 욱여넣는 코드를 실무에서 종종 보게 됩니다. 개인적으로는 컴프리헨션 한 줄이 너무 길어지거나 조건이 두 개 이상 겹치기 시작하면, 오히려 일반 for 문으로 풀어 쓰는 것이 협업 시 가독성 측면에서 더 낫다고 생각합니다. 반면 제너레이터는 실무에서 그 가치에 비해 상대적으로 저평가되는 개념이라고 봅니다. 대용량 로그 파일 처리나 데이터 파이프라인에서 리스트 대신 제너레이터를 쓰는 것만으로도 메모리 사용량을 크게 줄일 수 있는데, 입문 단계에서는 "결과를 눈으로 바로 확인하기 어렵다"는 이유로 리스트보다 덜 선호되는 경향이 있습니다. 이 부분은 학습 곡선의 문제일 뿐, 실무 효용 면에서는 제너레이터를 적극적으로 익혀둘 가치가 충분하다고 봅니다.

4. 추천 대상

  • 반복문과 조건문을 활용한 데이터 가공을 자주 하는 파이썬 입문·중급자
  • 대용량 파일이나 스트리밍 데이터를 다루는 데이터 엔지니어, 백엔드 개발자
  • 메모리 효율을 고려한 파이썬 코드 작성법을 배우고 싶은 개발자

5. FAQ

Q1. 리스트 컴프리헨션과 제너레이터 표현식의 차이는 무엇인가요?
문법상으로는 대괄호([])를 쓰면 리스트 컴프리헨션이고 소괄호(())를 쓰면 제너레이터 표현식입니다. 리스트 컴프리헨션은 결과를 즉시 리스트로 만들어 메모리에 저장하지만, 제너레이터 표현식은 값을 필요할 때마다 하나씩 계산해서 반환합니다.

Q2. 제너레이터를 리스트로 바꾸려면 어떻게 하나요?
list(제너레이터객체)처럼 list() 함수로 감싸면 제너레이터가 만들어내는 모든 값을 한 번에 리스트로 변환할 수 있습니다. 다만 이 경우 메모리 효율이라는 제너레이터의 장점은 사라집니다.

Q3. yieldreturn은 어떻게 다른가요?
return은 함수를 즉시 종료하고 값을 반환하지만, yield는 함수 실행을 일시 정지하고 값을 반환한 뒤, 다음 호출 시 정지했던 지점부터 실행을 이어갑니다.

6. 출처

 


소개 및 문의 · 개인정보처리방침 · 면책조항

© 2026 ⚡ 정보 부스터 🚀