이터레이터(iterator) or 반복자는 값을 차례대로 꺼낼 수 있는 객체(object)입니다.
(반복 가능한 객체)
만약 연속된 숫자를 미리 만들면 숫자가 적을 때는 상관없지만 숫자가 아주 많을 때는 메모리를 많이 사용하게 되므로 성능에도 불리합니다. 그래서 파이썬에서는 이터레이터만 생성하고 값이 필요한 시점이 되었을 때 값을 만드는 방식을 사용합니다. 즉, 데이터 생성을 뒤로 미루는 것인데 이런 방식을 지연 평가(lazy evaluation)라고 합니다.
li = [1, 2, 3] print(dir(li)) # ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', <== 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']
__iter__
함수는 이터레이터 객체이며, 안을 뜯어보면 __next__
함수가 존재하는것을 확인 할 수 있다.li = [1, 2, 3] iter_li = li.__iter() print(dir(iter_li)) #['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__length_hint__', '__lt__', '__ne__', '__new__', '__next__', # < == __next__ 함수 포함 '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
__next__
메소드를 사용하여 하나씩 호출li = [1, 2, 3] iter_li = li.__iter__() - print(iter_li) # <list_iterator object at 0x7ff2da82ff70> print(iter_li.__next__()) # 1 print(iter_li.__next__()) # 2 print(iter_li.__next__()) # 3 print(iter_li.__next__()) # StopIteration
'Hello, world!'.__iter__() #__next__ 호출시 H, e,~, ! <str_iterator object at 0x03616770> {'a': 1, 'b': 2}.__iter__() #__next__ 호출시 'a', 'b' <dict_keyiterator object at 0x03870B10> {1, 2, 3}.__iter__() #__next__ 호출시 1, 2, 3 <set_iterator object at 0x03878418>
it = range(3).__iter__() it.__next__() # 1 it.__next__() # 2 it.__next__() # 3 it.__next__() # StopIteration
정리하자면 반복 가능한 객체는 요소를 한 번에 하나씩 가져올 수 있는 객체이고, 이터레이터는
__next__
메서드를 사용해서 차례대로 값을 꺼낼 수 있는 객체입니다.
# for key in D.keys():
# print(key)
# print(D.keys([0])) # a
# b
# c
D = {'a':1, 'b':2, 'c':3}
it = iter(D)
n=1
while True :
try:
print(next(it))
except StopIteration:
print("ERROR")
break # a
# b
# c
# ERROR