이번 포스팅에서는 파이썬의 Iterator(반복자)에 대하여 공부를 해보고자 한다.
Iterable/Iterator
Iterable은 반복 조회가 가능한 객체를 말한다.
for in 문을 통해 값들을 순차적으로 제공해주는 객체라고 생각하면 된다. (리스트, 튜플, 셋, 문자열 등)
한번 반복 시마다 값을 하나씩 제공한다.
__iter__(self) 특수메소드를 정의하고 Iterator 객체를 반환한다.
__iter__(self) 메소드는 iter(iterable) 함수 호출 시 실행된다.
Iterator는 자신을 생성한 iterable의 값을 하나씩 제공하는 객체를 말한다.
__next__(self) 특수메소드를 정의하고 iterable의 원소를 순서대로 하나씩 제공한다.
더 이상 제공할 원소가 없을 경우 StopIteration 예외를 발생시킨다.
__next__(self) 특수 메소드는 next(iterator) 호출 시 실행된다.
예제
순서 1. 리스트를 생성한다. → Iterable
순서 2. iterable의 __iter__( )를 호출한다. → Iterator를 반환
순서 3. iterator의 __next( )를 호출한다. → list의 원소를 하나씩 제공
l = [1, 2, 3]
l_iterator = iter(l)
print(next(l_iterator))
print(next(l_iterator))
print(next(l_iterator))
print(next(l_iterator))
[실행결과]
1
2
3
StopIteration # error 발생
더 이상 제공할 원소가 없으면 StopIteration Exception을 발생시킨다.
Iterator(반복자)
for in 문 구현
iterator = nums.__iter__()
while True:
try:
num = iterator.__next__()
print(num)
except StopIteration:
break
for in 문이 반복자 객체를 순환 조회하는 과정
- 반복 조회할 iterable객체의 __iter__( ) 를 호출하여 Iterator를 구한다.
- 매 반복마다 Iterator의 __next__( ) 를 호출하여 다음 원소를 조회하고 다음 위치로 이동시키고, 모든 요소를 다 읽을 때까지 반복한다.
- 모든 요소를 다 제공하면 Iterator는 StopIteration 예외를 발생시키고 for in문은 반복을 종료한다.
Iterable/Iterator 클래스 구현
보통 Iterable 클래스에 Iterator 기능을 추가해서 구현한다.
__iter__( ) 메소드 구현
- Iterable이 구현해야 하는 메소드.
- Iterator(__next__() 메소드를 가지고 원소를 제공하는 객체)를 반환.
__next__( ) 메소드 구현
- Iterator가 구현해야 하는 메소드
- 원소를 순차적으로 반환하도록 구현한다.
- 모든 원소를 반환했을 때는 StopIteration 예외를 발생시킨다.
예제
Iterable을 구현
class MyIterable:
def __init__(self, *args):
"""
initializer에서 가변인자를 통해 제공해줄 값들을 tuple받아서 저장.
"""
self.values = args # tuple
def __str__(self):
"""제공할 원소들을 가진 tuple을 문자열로 반환"""
return str(self.values)
def __iter__(self):
"""원소들을 하나씩 제공할 Iterator객체를 반환"""
print("MyIterable.__iter__()")
return MyIterator(self)
Iterator를 구현 → MyIterable의 원소들(self.values)을 제공.
class MyIterator:
def __init__(self, iterable):
"""
제공해줄 원소를 가지고 있는 Iterable을 인자로 받아서 attribute로 저장.
몇번째 원소를 제공했는지를 저장할 변수(index)도 저장.
"""
self.iterable = iterable
self.index = 0
def __next__(self):
"""
next(iterator) 에 의해 호출되는 메소드
Iterable의 원소를 next()마다 하나씩 제공해주는 메소드
"""
print("MyIterator.__next__()호출")
# self.iterable: MyIterable 객체
values = self.iterable.values
if len(values) <= self.index:
raise StopIteration()
ret_values = values[self.index]
self.index += 1
return ret_values
순서 1. 리스트를 생성한다. → Iterable
순서 2. iterable의 __iter__( )를 호출한다. → Iterator를 반환
순서 3. iterator의 __next( )를 호출한다. → list의 원소를 하나씩 제공
m_iterable = MyIterable(10, 5, 20, 7)
m_iterator = iter(m_iterable)
print(next(m_iterator))
print(next(m_iterator))
print(next(m_iterator))
print(next(m_iterator))
print(next(m_iterator))
[실행결과]
MyIterator.__next__()호출
10
MyIterator.__next__()호출
5
MyIterator.__next__()호출
20
MyIterator.__next__()호출
7
MyIterator.__next__()호출
StopIteration
'Back-End > Python' 카테고리의 다른 글
[Python] Local(지역) 함수 (2) | 2022.10.05 |
---|---|
[Python] Generator(제너레이터) (0) | 2022.10.04 |
[Python] 내장함수(Built-In Function) (4) | 2022.10.02 |
[Python] Pickle을 이용한 객체 입출력 (0) | 2022.10.02 |
[Python] 텍스트 파일 입출력 (0) | 2022.10.02 |