Iterable과 Iterator의 정의
Iterable 객체의 정의와 확인하는 방법
Iterable은 내부에 __iter__ 메서드가 있는 모든 객체이며, 순회할 수 있는 객체이고 재사용이 가능합니다. Iterable에는 list, 문자열, dictionary, tuple, set과 같은 자료 유형이 이에 해당합니다.
객체가 Iterable인지 확인하는 방법은 아래 코드를 참고해 주세요.
from typing import Iterable
print(isinstance([1,2,3], Iterable)) # True
print(isinstance('abcd', Iterable)) # True
print(isinstance({1:'cal', 2:'jun'}, Iterable)) # True
print(isinstance((5,6,7), Iterable)) # True
print(isinstance(set([5,6,7]), Iterable)) # True
내부에 __iter__ 메서드가 있으면 모두 Iterable 객체로 인식할까요? 놀랍게도 그렇습니다.
아무 내용이 없는 의미 없는 'Temp'라는 Class를 만들었습니다. 그리고 그 안에 __iter__ 메서드를 선언만 했습니다. 그랬더니 파이썬은 Temp라는 Class를 Iterable 객체로 인식하고 있음을 확인할 수 있습니다.
class Temp:
def __init__(self):
pass
def __iter__(self, start, end):
pass
print(isinstance(Temp(), Iterable)) # True
Iterator 객체의 정의와 확인하는 방법
Iterator는 Iterable 객체에서 __iter__ 메서드를 통해 생성되는 객체입니다. 상태가 존재하기 때문에 한번 순회하면 재사용할 수 없습니다. 내부에 존재하는 __next__ 메서드를 통해 다음 값을 하나씩 차례대로 반환합니다. 마지막 원소까지 접근하여, 더 이상 반환할 수 있는 값이 없다면 StopIteration 에러를 반환하며 순회를 종료합니다.
list_a = [1,2,3,4,5]
itorator_a = list_a.__iter__()
print(type(itorator_a)) # <class 'list_iterator'>
iterator 객체인지 확인하는 방법은 아래 코드를 참고해 주세요.
from typing import Iterator
print(isinstance(itorator_a, Iterator)) # True
Iterable과 Iterator의 차이
Iterable 객체에서 __iter__ 메서드를 통해 생성되는 것이 Iterator 객체라고 말씀드렸습니다.
두 객체의 첫 번째 차이점은 Iterable 객체의 경우 순회 당하는 객체이고, Iterator 객체는 순회를 주관하는 객체라는 점입니다. 이 개념에 대해서는 뒷부분에 더 상세하게 설명드리도록 하겠습니다.
두 객체의 두 번째 차이점은 Iterable은 재사용할 수 있지만, Iterator는 재사용할 수 없습니다. 먼저 Iterable 객체인 list를 for 문으로 출력해 보겠습니다.
list_a = [1,2,3,4]
for i in list_a:
print(i, end = ' ')
# 코드 실행 결과값: 1 2 3 4
그리고 아래의 코드를 3번 정도 반복해 보겠습니다. 몇 번을 반복하더라도 "1 2 3 4"라는 값이 잘 출력됩니다.
for i in list_a:
print(i, end = ' ')
# 코드 결과값: 1 2 3 4
list_a에서 __iter__ 메서드를 통해 iterator_a를 만들었습니다.
list_a = [1,2,3,4]
iterator_a = list_a.__iter__()
print(type(iterator_a)) # <class 'list_iterator'>
그리고 iterator_a를 for문으로 한번 출력해 보겠습니다. "1 2 3 4"의 값이 잘 출력됩니다.
for i in iterator_a:
print(i, end = ' ')
# 코드의 결과값: 1 2 3 4
그럼 다시 한번 for문으로 출력해 볼까요? 놀랍게도 아무 값도 출력되지 않는 것을 확인할 수 있습니다. 이는 iterator_a가 재사용이 불가능한 1회성 객체이기 때문입니다. iterator_a를 처음 순회할 때, iterator_a의 상태는 '1'입니다.
1을 출력했으면, 다음 상태인 '2'로 이동합니다. 이렇게 마지막까지 순회하면 iterator_a의 상태는 '4'가 됩니다. 4 다음의 값, 상태는 없으므로 iterator_a는 다시 선언해주지 않는 이상, 재사용할 수 없습니다.
for i in iterator_a:
print(i, end = ' ')
# 아무 값도 출력되지 않음
for문으로 살펴보는 Iterable과 Iterator 객체의 동작 원리
Iterable 객체와 Iterator의 첫 번째 차이점이 Iterable 객체는 순회를 당하고, Iterator 객체는 순회를 한다고 말씀드렸습니다. 먼저 for문에 Iterable 객체를 넣으면 값이 어떻게 출력되는지 확인해 보겠습니다.
list_a = [1,2,3,4]
for i in list_a:
print(i)
# 위 코드의 결과값
1
2
3
4
이는 for 문을 배우신 분이라면 직관적으로 유추할 수 있는 결과입니다. 이 원리에 대해 설명드리겠습니다.
1. for문에 Iterable 객체를 넣어주면 내부의 __iter__ 메서드를 통해 임의의 Iterator를 만듭니다.
2. 만들어진 Iterator 내부의 __next__ 메서드를 통해 Iterator의 끝까지 값이 반환합니다.
3. Iterator의 마지막에 도달하면 StopIteration 에러를 발생시킵니다.
4. StopIteration 에러가 발생하면 for문을 종료합니다.
따라서 위 for문의 코드는 아래와 같이 바꿀 수 있습니다.
list_a = [1,2,3,4]
iterator_a = list_a.__iter__()
iterator_a.__next__() # 1
iterator_a.__next__() # 2
iterator_a.__next__() # 3
iterator_a.__next__() # 4
iterator_a.__next__() # StopIteration
이와 같은 작동 원리 때문에 Iterable 객체는 순회당하고, Iterator 객체는 순회를 주관한다고 표현할 수 있습니다. Iterable 객체를 순회하기 위해서 Iterator 객체를 수작업으로 선언할 필요는 없고, 반복문을 활용하면 이 과정을 자동화해 줍니다.
이상으로 Iterable, Iterator 객체에 대해 정리해 봤고, 다음 시간에는 직접 이 두 객체를 구현해 보는 시간을 갖도록 하겠습니다.
'Python > 기초' 카테고리의 다른 글
[파이썬/Python] 파일 쓰고 읽기: 파일 객체에 대한 총정리 (0) | 2023.07.07 |
---|---|
[파이썬/Python] Iterable과 Iterator 객체를 만들어 보자. (0) | 2023.07.06 |
[파이썬/Python] 얕은 복사(Shallow copy)와 깊은 복사(deep copy)에 대한 완벽 정리 (0) | 2023.07.05 |
[파이썬/Python] immutable과 mutable 객체 (0) | 2023.07.04 |
[파이썬/Python] 정수(Integer) 2탄: 메모리 할당 (0) | 2023.07.04 |
댓글