CodeGym /행동 /Python SELF KO /이터레이터

이터레이터

Python SELF KO
레벨 19 , 레슨 4
사용 가능

5.1 IterableIterator

너희도 알다시피, 이터레이터는 이터레이터 프로토콜을 구현하는 객체로 컬렉션에서 요소를 차례로 가져올 수 있게 해주는 애야. Python에서는 리스트, 튜플, 문자열 같은 시퀀스 요소를 순회할 때 이터레이터가 많이 사용돼.

이제, 이터레이터가 어떻게 구성되어 있고 어떻게 사용하는지 살펴보자.

이터러블 객체 (Iterable)

객체를 for 루프를 통해 순회하려면, 그 객체는 이터러블이어야 해 – Iterable. 이 말은, 우리의 객체가 메소드 __iter__()를 구현하고 있어야 한다는 뜻이고, 이 메소드는 이터레이터 객체를 반환해야 해.

이터레이터 객체 (Iterator)

이터레이터 객체는 특별한 객체로 다음 요소를 반환하는 함수 __next__()를 가지고 있어. 요소가 더 이상 없을 때, 메소드 __next__()는 예외 StopIteration을 호출하여 이터레이션을 중지해.

이터레이터는 또한 메소드 __iter__()를 구현해야 하고, 이 메소드는 자기 자신을 반환해야 해.

Python 내장 함수 사용 예제

이 예제에서 numbers 리스트는 이터러블 객체야. 우리는 iter() 함수를 사용하여 이터레이터를 얻고, next() 함수를 사용하여 StopIteration 예외가 발생할 때까지 요소를 순회할 수 있어.


# 이터러블 객체
numbers = [1, 2, 3, 4, 5]
            
# 이터러블 객체에서 이터레이터 얻기
iterator = iter(numbers)
            
# 이터레이터를 사용하여 요소 순회
try:
    while True:
        number = next(iterator)
        print(number)
except StopIteration:
    pass
        

바로 이게, 당신이 이런 코드를 쓸 때 일어나는 일이야:


# 이터러블 객체
numbers = [1, 2, 3, 4, 5]
            
for number in numbers:
    print(number)
        

5.2 이터레이터의 본질

이터레이터는 우리가 그룹의 요소들을 차례로 순회할 수 있도록 도와주는 어떤 객체야. 구현 방법은 매우 다양할 수 있지. 이제 이터레이터에 요구되는 모든 요건을 충족하는 클래스를 하나 만들어보자.

1단계. 시작으로 클래스를 만들어보자

이것은 start부터 end까지 숫자를 차례로 반환할 거야.


class MyIterator:
    def __init__(self, start, end):
        self.current = start
        self.end = end
        

2단계. __iter__ 함수 지원

이제 __iter__ 함수를 추가할 필요가 있어. 이 함수는 __next__() 함수를 호출할 수 있는 이터레이터 객체를 반환하게 할거야. 자기 자신의 객체를 반환해도 돼. 이건 금지된게 아니야.


class MyIterator:
    def __init__(self, start, end):
        self.current = start
        self.end = end
        
    def __iter__(self):
        return self
        

3단계. __next__ 함수 지원

이제, 우리의 이터레이터 객체에 __next__ 함수를 추가해야 해, 이 함수는 리스트의 다음 요소를 반환할 거야. 우리는 그냥 current 변수를 사용할 거야:


def __next__(self):
    current = self.current
    self.current += 1
    return current
        

4단계. 이터레이터 정지

이터레이터가 이미 계획된 모든 값을 반환한 경우, StopIteration 예외를 던져야 해. 이제 마지막 함수를 조금 수정해보자:


def __next__(self):
    if self.current >= self.end: raise StopIteration
    current = self.current
    self.current += 1
    return current
        

좋아. 이제 우리 이터레이터를 사용할 수 있어. 여기가 전체 코드의 예야:


class MyIterator:
    def __init__(self, start, end):
        self.current = start
        self.end = end
        
    def __iter__(self):
        return self
        
    def __next__(self):
        if self.current >= self.end:
            raise StopIteration
        current = self.current
        self.current += 1
        return current
        
# 사용자 이터레이터 인스턴스 생성
my_iter = MyIterator(1, 5)
        
# 이터레이터를 사용하여 요소 순회
for num in my_iter:
    print(num)

5.3 올바른 이터레이터

이전 예제의 이터레이터가 어때서? 맞아, 이터레이터고 작동해, 하지만 너무 단순해. 동일한 요소 컬렉션을 동시에 여러 이터레이터로 순회할 수 없어.

더 나은 방법은 __iter__ 메소드에서 자기 자신이 아닌 별도의 객체를 반환하여 모든 요소를 올바르게 반환하는 것이야.

예제:


class MyIterable:
    def __init__(self, data):
        self.data = data
    
    def __iter__(self):
        return MyIterator(self.data)
    
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):
            raise StopIteration
        item = self.data[self.index]
        self.index += 1
        return item
    
# 사용 예제
my_iterable = MyIterable([1, 2, 3, 4])
for item in my_iterable:
    print(item)
    

이 예제에서는 두 개의 클래스가 있어 — 첫 번째는 우리가 이터레이터로 순회할 컬렉션을 전달하는 클래스이고, 두 번째는 이터레이터 자체로, next() 메소드에서 컬렉션의 요소를 반환해. 이건 꽤 간단하지만, 바로 이렇게 이터레이터를 클래스에 추가해야 해.

1
설문조사/퀴즈
모듈과 패키지, 레벨 19, 레슨 4
사용 불가능
모듈과 패키지
모듈과 패키지
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION