이터레이터(iterator)는 값을 차례대로 꺼내올 수 있는 객체이다.
파이썬에서는 이터레이터만 생성하고 값이 필요한 시점이 되었을 때 값을 만드는 방식을 사용한다. 데이터 생성을 뒤로 미루는 것인데 이런 방식은 지연 평가(lazy evaluation)라고 한다.
이터레이터가 무엇인지 제대로 이해하기 위해서는 먼저 반복 가능한 객체에 대해서 알아야 한다.
반복 가능한 객체는 요소가 여러 개 들어있고, 한 번에 하나씩 꺼낼 수 있는 객체이다. 문자열, 리스트, 딕셔너리, 세트 등이 반복 가능한 객체이다.
반복 가능한 객체인지 확인하려면 dir 함수를 사용하여 __iter__ 메서드 들어있는지 확인해보면 된다.
>>> 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']
리스트 [1, 2, 3]을 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
리스트의 인덱스를 벗어나서 가져올 값이 없으면 StopIteration이 발생한다.
__iter__, __next__ 함수 대신 편하게 내장 함수인 iter(), next()를 사용할 수 있다.
아래와 같이 리스트의 값마다 제곱을 하는 for문을 iter()와 next() 함수를 적용해서 while문으로 구현해보겠다.
L = [1, 2, 3]
for x in L:
print(x ** 2, end=' ')
L = [1, 2, 3]
I = iter(L)
while True:
try:
X = next(I)
except StopIteration:
break
print( X**2, end=" ")
간단한 키를 출력하는 딕셔너리에 대한 for 문을 while문으로 구현해보겠다.
D = {'a':1, 'b':2, 'c':3}
for key in D.keys():
print(key)
D = {'a':1, 'b':2, 'c':3}
I = iter(D)
while True:
try:
X = next(I)
except StopIteration:
break
print(X, end=" ")
개념정리
- 반복 가능한 객체는 요소를 한 번에 하나씩 가져올 수 있는 객체이다.
- iter() 함수는 반복가능한 객체에서 이터레이터를 꺼내 반환한다.
- next() 함수는 이터레이터를 입력받아 그 이터레이터가 다음에 출력해야 할 요소를 반환한다.
참고사이트 :
https://python.bakyeono.net/chapter-7-4.html
https://dojang.io/mod/page/view.php?id=2405
http://pythonstudy.xyz/python/article/23-Iterator%EC%99%80-Generator
https://nvie.com/posts/iterators-vs-generators/