대용량 데이터 처리
대용량 데이터를 효율적으로 다루고 싶다면?
이터레이터(iterator) 와 제너레이터(generator) 를 꼭 알아야 한다.
한 번에 하나씩 처리하고, 메모리도 절약할 수 있다.
1. 이터레이터 (Iterator)
데이터를 순차적으로 하나씩 꺼낼 수 있는 객체
예: 리스트, 튜플, 딕셔너리, 문자열 등 대부분의 컬렉션에 사용 가능하다.
1) 이터레이터 프로토콜
이터레이터가 되려면 다음 2가지 메서드를 구현해야 한다.
메서드 | 설명 |
---|---|
__iter__() |
자기 자신을 반환함. 이터러블임을 나타냄 |
__next__() |
다음 값을 반환. 끝나면 StopIteration 예외 발생 |
2) 이터러블 vs 이터레이터
구분 | 설명 | 예시 |
---|---|---|
이터러블 | iter() 가능 |
리스트, 문자열, 튜플 |
이터레이터 | next() 가능 |
파일 객체, 제너레이터 등 |
3) 이터레이터 직접 구현해보기
class NumberIterator:
def __init__(self, limit):
self.limit = limit
self.current = 0
def __iter__(self):
return self
def __next__(self):
if self.current < self.limit:
result = self.current
self.current += 1
return result
else:
raise StopIteration
# 사용 예시
for num in NumberIterator(5):
print(num)
# 출력: 0 1 2 3 4
4) enumerate() 함수
인덱스와 값을 동시에 순회할 수 있게 도와준다.
fruits = ['apple', 'banana', 'orange']
for i, fruit in enumerate(fruits, start=1):
print(f"{i}: {fruit}")
# 출력:
# 1: apple
# 2: banana
# 3: orange
for
문에서 인덱스가 필요할 때 매우 유용하다.
2. 제너레이터 (Generator)
yield
를 사용하여 하나씩 값을 생성하는 함수 기반 이터레이터
1) 제너레이터를 왜 사용할까?
• 한 번에 모든 데이터를 메모리에 올리지 않는다.
• 지연 평가(Lazy Evaluation)로 성능 최적화할 수 있다.
• 복잡한 계산 흐름도 깔끔하게 표현 가능하다.
2) 제너레이터 함수 예시
def count_up_to(n):
count = 0
while count < n:
yield count
count += 1
gen = count_up_to(3)
print(next(gen)) # 0
print(next(gen)) # 1
print(next(gen)) # 2
yield
는return
처럼 값을 내보내지만,
함수의 실행 상태를 멈췄다가 나중에 다시 이어서 실행할 수 있게 해준다.
3) next()와 StopIteration
• next() 호출 시 yield 다음 코드까지 실행한다.
• 더 이상 값이 없으면 StopIteration 발생한다.
4) 제너레이터 표현식
gen = (x * 2 for x in range(5))
for i in gen:
print(i)
# 출력: 0 2 4 6 8
리스트 컴프리헨션처럼 보이지만 () 사용한다. 메모리에 전부 담지 않고 하나씩 꺼내서 처리한다.
5) 제너레이터 활용 코드
def fibonacci_generator(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
for num in fibonacci_generator(5):
print(num)
# 출력: 0 1 1 2 3
3. 이터레이터 vs 제너레이터 요약
항목 | 이터레이터 | 제너레이터 |
---|---|---|
형태 | 클래스 구현 필요 | 함수 + yield |
상태 저장 | 직접 구현 | 자동으로 관리됨 |
코드 길이 | 상대적으로 길다 | 간결하다 |
메모리 효율 | 있음 | 더 좋음 |
대표 예시 | 파일 읽기, 리스트 순회 | 피보나치, 무한 시퀀스 생성 |
오늘을 마치며
이터레이터는 순차의 틀, 제너레이터는 효율의 기술이다.
이터레이터는 데이터를 하나씩 꺼내며 흐름을 차분히 이끌어주고,
제너레이터는 꼭 필요할 때만 살짝살짝 값을 내어주며 가볍고 유연하게 도와준다.
두 도구가 만나면,
무거운 데이터도 부담 없이 다룰 수 있고
복잡한 로직도 훨씬 더 간결하고 자연스럽게 풀어낼 수 있다.