반응형
Step 4에서는 파이썬이 대용량 데이터를 다루는 핵심 기법인 이터레이션 프로토콜을 배웁니다. 수백만 개의 데이터를 메모리에 한 번에 올리지 않고도 효율적으로 처리할 수 있는 **제너레이터(Generator)**와 **이터레이터(Iterator)**의 원리를 파헤쳐 봅시다.
1. 🔄 이터러블(Iterable)과 이터레이터(Iterator)
파이썬에서 for 루프를 돌릴 수 있는 객체는 모두 이터러블입니다. 하지만 그 내부 동작은 두 단계로 나뉩니다.
- Iterable: __iter__ 메서드를 가진 객체 (예: 리스트, 튜플, 문자열).
- Iterator: __next__ 메서드를 가진 객체로, 데이터의 다음 값을 하나씩 반환하며 상태를 유지합니다.
Python
nums = [1, 2, 3]
it = iter(nums) # nums.__iter__() 호출
print(next(it)) # 1
print(next(it)) # 2
print(next(it)) # 3
# print(next(it)) # StopIteration 예외 발생 (더 이상 값이 없음)
2. ⚡ 제너레이터(Generator): 양보(yield)의 미학
제너레이터는 이터레이터를 가장 쉽게 만드는 방법입니다. 일반 함수처럼 보이지만 return 대신 yield 키워드를 사용합니다.
- 지연 평가(Lazy Evaluation): 모든 결과값을 메모리에 미리 생성하지 않고, 값이 필요할 때마다 하나씩 생성하여 반환합니다.
- 상태 유지: yield를 만나면 함수 실행을 멈추고 값을 반환한 뒤, 다음 호출 시 멈췄던 지점부터 다시 실행합니다.
Python
def count_up_to(n):
count = 1
while count <= n:
yield count # 값을 반환하고 여기서 대기
count += 1
counter = count_up_to(3)
for num in counter:
print(num) # 1, 2, 3 출력
3. 📉 제너레이터 표현식 (Generator Expression)
리스트 컴프리헨션([])과 비슷하지만 소괄호(())를 사용합니다. 데이터가 아주 많을 때 리스트 대신 사용하면 메모리 사용량을 획기적으로 줄일 수 있습니다.
Python
# 리스트 컴프리헨션: 1억 개의 데이터를 메모리에 즉시 생성
# huge_list = [i for i in range(100000000)]
# 제너레이터 표현식: 하나씩 꺼내올 준비만 함 (메모리 사용 거의 없음)
huge_gen = (i for i in range(100000000))
print(next(huge_gen)) # 0
print(next(huge_gen)) # 1
💡 시니어의 조언: 왜 제너레이터를 써야 하는가?
실무에서 수십 기가바이트(GB) 규모의 로그 파일이나 DB 레코드를 읽어올 때, 리스트로 담으려 하면 MemoryError가 발생하며 프로그램이 뻗어버립니다. 이때 제너레이터를 활용하면 메모리를 아주 적게 쓰면서도 대량의 데이터를 안정적으로 처리할 수 있습니다. "필요할 때만 만든다"는 철학을 기억하세요.
반응형
'개발 > Python' 카테고리의 다른 글
| [중급반] Step 6. 메타 프로그래밍과 자원 관리: Metaclass와 Context Manager (0) | 2025.12.26 |
|---|---|
| [중급반] Step 5. 병렬성과 동시성: Multiprocessing과 Asyncio (0) | 2025.12.26 |
| [중급반] Step 3. 객체 지향 프로그래밍(OOP) 심화: 상속과 MRO (0) | 2025.12.26 |
| [중급반] Step 2. 일급 함수와 클로저: 함수를 데이터처럼 다루기 (0) | 2025.12.26 |
| [중급반] Step 1. 파이썬 데이터 모델: 매직 메서드(Magic Methods)의 비밀 (0) | 2025.12.26 |