이터러블 ( Iterable )
하나씩 차례대로 값을 꺼내올 수 있는 객체를 말한다.
- 정의: 반복 가능한 객체로, for 루프에서 순회할 수 있는 객체입니다.
예를 들어, 리스트, 튜플, 문자열, 딕셔너리, 세트 등이 이에 해당합니다. - 특징:
- __iter__() 메서드를 구현해야 합니다. 이 메서드는 이터레이터를 반환합니다.
- 순회할 수 있는 데이터를 제공하지만, 데이터를 실제로 순회하는 역할은 이터레이터가 합니다.
iterable = [1, 2, 3] # 리스트는 이터러블
for item in iterable:
print(item) # 1, 2, 3 출력
이터레이터( Iterator )
이터러블한 객체의 요소를 하나씩 꺼내오는 객체를 말한다.
- 정의: 이터러블 객체에서 __iter__() 를 호출하여 얻을 수 있는 객체로, __next__() 메서드를 통해 데이터를 하나씩 반환합니다.
- 특징:
- __iter__() 메서드: 이터레이터 자신을 반환합니다. (이터레이터는 스스로 이터러블이기도 합니다.)
- __next__() 메서드: 다음 값을 반환하며, 더 이상 반환할 값이 없으면 StopIteration 예외를 발생시킵니다.
iterable = [1, 2, 3]
iterator = iter(iterable) # 이터레이터 생성
print(next(iterator)) # 1
print(next(iterator)) # 2
print(next(iterator)) # 3
print(next(iterator)) # StopIteration 예외 발생
더보기
class MyIterator:
def __init__(self, data):
self.data = data
self.index = 0
def __iter__(self):
return self
def __next__(self):
if self.index < len(self.data):
result = self.data[self.index]
self.index += 1
return result
else:
raise StopIteration
# 이터레이터 사용
my_iter = MyIterator([1, 2, 3])
for item in my_iter:
print(item)
제너레이터 ( Generator )
이터레이터를 생성하는 간단한방법으로, 함수 형태로 작성
상태를 유지하면서 데이터를 하나씩 반환하므로, 메모리를 절약하고 효율적으로 데이터 처리가 가능
- yield 키워드 사용:
- 제너레이터 함수에서 값을 반환할 때 yield 를 사용합니다.
- yield 를 호출하면 현재 함수 상태를 저장하고, 호출한 곳으로 값을 반환합니다.
- 다음 호출 시 이전 상태에서 다시 실행을 이어갑니다.
- 이터레이터 구현:
- 제너레이터 함수는 자동으로 __iter__() 와 __next__() 메서드를 구현한 객체를 반환합니다.
- 따라서 이터레이터처럼 사용할 수 있습니다.
- 지연 계산(Lazy Evaluation):
- 값을 필요할 때마다 하나씩 생성합니다.
- 대량의 데이터를 처리할 때 메모리 사용을 최소화합니다.
def simple_generator():
yield 1
yield 2
yield 3
# 제너레이터 사용
gen = simple_generator()
print(next(gen)) # 1
print(next(gen)) # 2
print(next(gen)) # 3
print(next(gen)) # StopIteration 예외 발생
제너레이터의 내부 동작
제너레이터는 함수 실행을 중단(pause) 하고 상태를 유지한 뒤,
필요한 값을 생성(resume) 합니다.
- next() 호출 -> yield 까지 실행 -> 값 반환 -> 실행 멈춤
- 다시 next() 호출 -> 멈췄던 위치에서 실행 재개 -> 다음 yield 까지 실행
제너레이터 표현식
- 리스트 컴프리헨션과 비슷한 문법으로 제너레이터 작성 가능
- 제너레이터 표현식은 () 를 사용
gen_exp = (x * x for x in range(5))
for value in gen_exp:
print(value)
# 출력
0
1
4
9
16
요약
제너레이터와 이터레이터는 상당히 비슷하다.
클래스를 이용해 이터레이터를 작성하면 좀 더 복잡한 행동을 구현할 수 있다.
이와 달리 제너레이터를 이용하면 간단하게 이터레이터를 만들 수 있다.
따라서 이터레이터의 성격에 따라 클래스로 만들 것인지, 제너레이터로 만들 건인지를 선택해야함!
'Python > Python 기초' 카테고리의 다른 글
[Python] 함수 심화 - 고차함수 (6) | 2024.12.10 |
---|---|
[Python] 데코레이터( @ ), 컨텍스트 매니저 ( with ) (2) | 2024.12.02 |
[Python] 파일 다루기 (0) | 2024.12.01 |
[Python] 클래스 ( class ) (7) | 2024.12.01 |
[Python] 예외 처리 ( try, except, finally ), 에러 타입 (1) | 2024.12.01 |