개발자 블로그

[윤성우의 열혈 파이썬 중급편] - 4. Iterable 객체와 Iterator 객체 본문

파이썬/윤성우의 열혈 파이썬 중급편

[윤성우의 열혈 파이썬 중급편] - 4. Iterable 객체와 Iterator 객체

hayongwoon 2022. 4. 26. 20:59

iter 함수

하나 이상의 값을 저장하거나 꺼내보는 것은 빈번하고 중요한 일이다. 보편적으로 for문을 사용하여 2개 이상의 값들을 꺼내보는 작업을 했는데, 이러한 작업이 중요하기에 상황에 따라 우리는 유연하게 대처할 필요가 있다.

 따라서 이번에 소개할 방법은 원하는 시기에 필요에 따라 값을 꺼낼 수 있는 iterator 객체를 설명하고자 한다.

>>> ds = [1,2,3,4]
>>> ir = iter(ds)
>>> next(ir)
1
>>> next(ir)
2
>>> next(ir)
3
>>> next(ir)
4
>>> next(ir)
Traceback (most recent call last):
	File ~~~~~~
    	next(ir)
    StopIteration

iter 함수 코드 정리를 하면 이런대 더 이상 호출할게 없으면 StopIteration 예외가 발생한다. 반복을 하고 싶다면 또 다시 Iter 함수로 iterator 객체를 생성해주면 된다.

 

Iterator 객체와 Iterable 객체

iter 함수가 반환하는 객체를 가리켜 'iterator 객체'라고 하고, iter 함수에 인자로 들어갈 수 있는 객체를 iteralbe 객체라고 한다. 말 그대로 iter(사용가능한)able 객체이다. 대표적으로 리스트, 튜플, 문자열 등이 있고 iterable 객체인지 확인하는 방법으로는 hasattr() 함수를 활용하여 해당하는 객체가 iterable 객체인지 알 수 있다. 아래 코드로 설명을 하겠다.

>>> hasattr([1,2], '__iter__')   # 리스트에 __iter__ 함수가 있나요??
True

이와 같은 방법으로 확인한고 iter 함수를 사용하면 되겠다.

 

for 루프와 Iterable 객체

우리가 정말 많이 사용하는 for문도 사실 iterable 객체를 생성해서 이것의 도움을 받는다. 

>>> for i in [1,2,3]:
	print(i, end='')
    
1 2 3

위 코드의 내부를 살펴보자!

>>> ir = iter([1,2,3])  #iterator 객체를 만든다.
>>> while True:
        try:
            i = next(ir)         # iterator 객체를 통해 값을 하나 씩 가져온다.
            print(i, end = ' ')
        except StopIteration:     # 더 이상 꺼낼 값이 없다면, while loop를 탈출!
            break
1 2 3

for 문의 내부를 살펴보니 반복 대상이 iterator 객체임을 알 수 있다. 이 말은 즉슨 for문에 사용되는 객체는 iterable 객체라고 할 수 있다.

따라서 문자열, 튜플, 리스트 객체가 for loop의 대상이 될 수 있는 것이다.

 

여기서 궁금한 점이 생기는데, 그렇다면 iterator 객체는 for 문에 돌아갈까? 즉, iterator 객체가 iterable 객체가 될 수 있을까? 하는 의문이다. 우선 답을 먼저 내자면 동작이 가능하다! 코드를 보며 자세히 살펴보자!

>>> ir = iter([1,2,3])      # ir에 저장되는 것은 iterator 객체
>>> for i in ir:            # for loop에 iterator 객체를 가져다 둠.
    	print(i, end = ' ')
1 2 3

iterator 객체를 iter 함수의 인자로 들어가도 값이 잘 나온 이유는 전달된 iterator 객체를 새롭게 만든것이 아니라 그대로 반환했기 때문이다.

>>> ir1 = iter([1,2,3])
>>> ir2 = iter(ir1)  # 그대로 반환!!
>>> ir1 is ir2       # 참조하는 객체가 같다!!
True 
>>> id(r1)           # r1 메모리 주소
12345
>>> id(r2)			 # 메모리 주소가 동일한 것을 확인!!
12345

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