[Python] Iterable객체와 Iterator객체

2 분 소요

iter 함수

>>> ds = [1,2]
>>> ir = iter(ds) # iterator 객체를 얻는 방법
>>> next(ir)
1
>>> next(ir)
2
>>> next(ir)
Trackback (most recent call last):
    File "<pyshell#17>", line 1, in <module>
        next(ir)
StopIteration
>>> ir = iter(ds)
>>> next(ir)
1

iter라는 함수를 호출해 리스트를 전달했다. iter함수는 객체를 생성해서 반환하는데 이는 리스트에서 값을 꺼내는 기능을 제공하는 객체이다.

즉 iter함수는 리스트 ds에 접근하는 도구인 ‘iterator’객체를 생성해서 반환한다. 즉 ir는 ‘iterator’객체를 참조하는 상황이다.

마지막 값을 얻었음에도 next함수를 호출하면 위 코드와 같이 StopIteration 예외가 발생.

처음부터 값을 다시 얻고싶다면 iterator 객체를 다시 얻으면 된다.

for 루프의 반복 대상은 반드시 ‘iterable 객체’여야 한다. 그래서 리스트, 튜플, 문자열은 for 루프의 반복 대상이 될 수 있다.

>>> ds = [1,2]
>>> ir = iter(ds) # iterator 객체를 얻는 방법
>>> for i in ir:
        print(i, end=' ')
1 2

for루프에 iterable 객체가 아닌 iterator 객체를 두어도 정상적으로 동작한다. 그 이유는 iter함수에 iterator 객체를 전달하면 전달된 iterator 객체를 그대로 되돌려 주기 때문이다.

>>> ir1 = iter([1,2,3])
>>> ir2 = iter(ir1)
>>> ir1 is ir2
True
>>> id(ir1)
56478576
>>> id(ir2)
56478576

iterable 객체와 iterator 객체 모두 for 루프의 반복 대상이 될 수 있고 iterable 객체가 와야 하는 위치에는 iterator 객체가 올 수 있다.

이는 iterable 객체와 마찬가지로 iterator 객체도 iter함수의 인자가 될 수 있고 또 그 결과로 iterator 객체가 반환되기 때문이다.



iterable 객체와 iterator 객체의 구분

iter 함수가 반환하는 개체를 가리켜 ‘iterator 객체’(아이터레이터 객체)라 하고 iterator 객체를 얻을 수 있는 리스트와 같은 객체를 가리켜 iterable 객체(아이터러블 객체)라 한다.

Iterable 객체 : iter함수에 인자로 전달 가능한 객체 Iterator 객체 : iter함수가 생성해서 반환하는 객체

“iterable 객체를 대상으로 iter함수를 호출해서 iterator 객체를 만든다.”

“iterator 객체를 생성할 수 있는 대상이 되는 것이 iterable 객체이다.”

스페셜 메소드

>>> ds = [1,2]
>>> ir = iter(ds) # iterator 객체를 얻는 방법
>>> next(ir)
1
>>> next(ir)
2
>>> ds = [1,2]
>>> ir = ds.__iter__() # iter 함수 호출의 실제 모습
>>> ir.__next__()  # next 함수 호출의 실제 모습
1
>>> ir.__next__()
2

리스트의 iter 메소드 호출을 통해서 iterator 객체를 얻고 iterator 객체의 next 메소드 호출을 통해서 값을 하나씩 얻게 된다.

이렇게 직접 호출하지 않아도 파이썬 인터프리터에 의해서 호출되늰 메소드를 가리켜 스페셜 메소드(Special Method) 파이썬 인터프리터에 의해서 호출되는 메소드 라고 부른다.

객체 생성 시 자동으로 호출되는 init 메소드도 스페셜 메소드이다.

Iterable 객체의 종류와 확인 방법

위에서 리스트를 통해서 iterator 객체를 얻었다. 튜플이나 문자열을 통해서도 iterator 객체를 얻을 수 있다.

“즉 리스트, 튜플, 문자열 모두 iterator 객체를 반환하는 iterable 객체이다.”

>>> dir([1,2]) # dir(list)
['__add__', '__class__', ... '__iter__' , ... 'sort']
>>> hasattr([1,2], '__iter__')
True

dir 함수를 호출해 __iter__메소드가 존재하는지 확인하는 방법과 hasattr 함수 호출을 통해 __iter__함수가 있는지 True, False로 답을 얻을 수 있다.