이터레이터: 저장 방식과 순회를 분리하기
사용하는 쪽에서는 자료가 배열인지 연결 리스트인지 몰라도 값을 차례대로 받고 싶습니다. 이터레이터 패턴은 자료의 내부 표현을 드러내지 않으면서 순회할 방법을 제공합니다.
Python의 iter와 next
class Shelf:
def __init__(self, books):
self.books = list(books)
def __iter__(self):
return iter(self.books)
shelf = Shelf(["one", "two"])
iterator = iter(shelf)
print(next(iterator))
print(list(iterator))
print(list(shelf))
첫 줄은 one, 둘째 줄은 ['two'], 셋째 줄은 ['one', 'two']입니다. iterator는 어디까지 읽었는지 기억합니다. 한 값을 꺼낸 뒤 남은 값을 읽으면 첫 값은 다시 나오지 않습니다. Shelf는 호출할 때마다 새 이터레이터를 만들어 처음부터 순회할 수 있습니다.
for문은 이러한 순회 약속을 이용합니다. generator의 yield를 사용하면 필요할 때 다음 값을 계산하는 순회도 만들 수 있습니다. 모든 값을 미리 리스트에 담지 않을 수 있지만, 원본 자료가 이미 메모리에 있다면 그 저장 공간까지 사라지는 것은 아닙니다.
순회 중 수정은 주의합니다
자료를 읽는 중에 원소를 추가하거나 삭제하면 결과가 자료구조와 구현에 따라 달라질 수 있습니다. 순회 대상을 복사하거나 수정을 나중에 모아서 처리하는 방법을 고려하세요.
확인 문제
한 이터레이터를 끝까지 읽고 같은 이터레이터로 다시 반복하면 처음부터 나올까요?
해설 보기
일반적인 이터레이터는 소진된 상태를 유지합니다. 다시 읽으려면 반복 가능한 원본에서 새 이터레이터를 만들어야 합니다. 파일이나 네트워크처럼 다시 읽기가 제한되는 원본도 있습니다.