이터레이터(iterator) : 값을 차례대로 꺼낼 수 있는 객체(object)
for 반복문을 사용할 때 range 사용의 예를 보겠습니다.
for i in range(100): 의 range 는 0부터 99까지 연속된 숫자를 만들어낸다고 했는데,
사실은 숫자를 모두 만들어 내는 것이 아니라 0부터 99까지 값을 차례대로 꺼낼 수 있는 이터레이터를 하나만 만들어냅니다. 이후 반복할 때마다 이터레이터에서 숫자를 하나씩 꺼내서 반복합니다.
만약 연속된 숫자를 미리 만들면 숫자가 적을 때는 상관없지만 숫자가 아주 많을 때는 메모리를 많이 사용하게 되므로 성능에도 불리합니다. 그래서 파이썬에서는 이터레이터만 생성하고 값이 필요한 시점이 되었을 때 값을 만드는 방식을 사용합니다. 즉, 데이터 생성을 뒤로 미루는 것인데 이런 방식을 지연 평가(lazy evaluation)라고 합니다.
참고로 이터레이터는 반복자라고 부르기도 합니다.
이런 이터레이터를 어디에서 사용할 수 있느냐 ?
바로 반복가능한 객체 안에서만 사용이 가능합니다.
우리가 흔히 사용하는 문자열,리스트,딕셔너리,세트 등이 이에 해당됩니다. 쉽게 말하자면 요소가 여러개 들어있고 한번에 하나씩 꺼낼 수 있는 객체를 말합니다.
만약 객체가 반복 가능한 객체인지 알고싶으면 dir
함수를 사용해보면 알 수 있습니다.
>>> dir([1, 2, 3])
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
위와같이 리스트를 dir로 살펴보면 iter 메서드가 들어있고, 아래처럼 iter 을 호출해보면 이터레이터가 나옵니다.
>>> [1, 2, 3].__iter__()
<list_iterator object at 0x03616630>
이 이터레이터에서 next를 호출하면 차례대로 값을 꺼냅니다.
>>> it = range(3).__iter__()
>>> it.__next__()
0
>>> it.__next__()
1
>>> it.__next__()
2
>>> it.__next__()
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
it.__next__()
StopIteration
이처럼 반복 가능한 객체는 iter 메서드로 이터레이터를 얻고, 이터레이터의 next 메서드로 반복합니다.