본문 바로가기
Python

[Python] Iterators

by 혀넝 2022. 3. 6.

iterator란, iterable 객체에서 값을 차례대로 꺼낼 수 있는 객체를 말한다. iterable 객체는 list, dictionary, set, str, tuple, range 등이 있다.

우리는 리스트가 있을 때 for문을 사용하여 값을 하나씩 불러왔다. 
아래 예제는 for문을 통해 값마다 제곱을 하는 코드이다.

L = [1, 2, 3] 

for x in L:
	print(x ** 2, end=' ')
    
>>> 1, 4, 9

리스는 L이 반복 가능한 객체인지 확인하는 방법은 dir를 사용하는 것이다. dir(객체)를 호출하면 해당 객체가 어떠한 변수와 메서드를 가지고 있는 보여준다.

print(dir(L))

>>>
['__add__', '__class__', '__class_getitem__', '__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']

출력된 결과에서 __iter__함수가 들어있는 것을 볼 수 있다. 해당 함수가 있으면 dir에 사용된 객체가 iterator 객체임을 알 수 있다.
직접 확인해 보고 싶으면 객체.__iter()__를 호출해 보면 된다.

print(L.__iter__())

>>>
<list_iterator object at 0x102e164d0>

 

그 후 iterator를 변수에 저장 후 __next__함수를 호출하면 for문과 같이 값을 하나씩 꺼내올 수 있다.

iterator_L = L.__iter__()

print(iterator_L.__next__())
print(iterator_L.__next__())
print(iterator_L.__next__())

>>>
1
2
3

리스트 L에는 값이 세 개 들어있다. 만약 iterator_L.__next__()를 네 번 호출하게 되면, 세 값은 잘 출력된 다음에 StopIteration이 발생한다.

지금까지 __iter__함수와 __next__함수를 사용했는데, 같은 역할을 하는 게 내장 함수인 iter()와 next()이다.

L = [1,2,3,4]

I = iter(L)

while True:
    try:
        X = next(I)
    except StopIteration:
        break
    print( X**2, end=" ")

>>>
1 4 9 16

 

과제

딕셔너리도 반복 가능한 객체라서 앞서 본 리스트와 같이 __iter__함수와 __next__함수를 사용할 수 있고 파이썬 기본 함수인 iter, next 또한 사용할 수 있습니다. 다음의 간단한 키를 출력하는 딕셔너리에 대한 for 문을 while문으로 구현해 보세요.

D = {'a':1, 'b':2, 'c':3}
I = iter(D.keys())

while True:
    try:
        X = next(I)
    except StopIteration:
        break
    print(X)
    
>>>
a
b
c

*키를 출력하는 문제라서 keys()를 사용했지만, 만약 value를 출력하는 문제라면 values()를 사용하면 된다.