728x90
1. Iterator
- 순서대로 다음 값을 리턴할 수 있는 객체를 의미
- Iterator는 자체적으로 내장하고 있는 next 메소드를 통해 다음 값을 가져올 수 있음
2. Iterable
- 내부 요소(member)를 하나씩 리턴할 수 있는 객체
- Iterable한 것은 __next__ 메소드가 존재하지 않음
- 내부에 __Iter__라는 메소드를 가지고 있음
- for문을 통해 순회할 수 있는 객체를 Iterable하다고 함
컬렉션 타입(컨테이너 타입)
set, dictionary와 같이 여러개의 요소(객체)를 갖는 데이터 타입
시퀀스 타입
list, tuple, range, str등과 같이 순서가 존재하는 데이터 타입
위의 타입들은 전부 iterable하지만, iterator는 아니다.
a = list()
b = set()
c = "str"
d = dict()
e = tuple()
f = range(1,3)
#print(a.__next__) AttributeError: 'list' object has no attribute '__next__'
#print(b.__next__) AttributeError: 'set' object has no attribute '__next__'
#print(c.__next__) AttributeError: 'str' object has no attribute '__next__'
#print(d.__next__) AttributeError: 'dict' object has no attribute '__next__'
#print(e.__next__) AttributeError: 'tuple' object has no attribute '__next__'
#print(f.__next__) AttributeError: 'range' object has no attribute '__next__'
Iterable한 객체 To Iterator
iterable한 객체를 iter()메소드를 통해 Iterator로 만들 수 있음
a = [1,2,3]
#리스트는 iterator가 아니다.
#print(a.__next__) 실행시 오류발생
a = iter(a)
print(type(a))# list_itertor 출력
print(a.__next__())# 첫 실행 시 1출력
print(next(a))#다음과 같은 방법으로도 출력이 가능하다. 2출력
print(a.__next__())#3출력
#print(a.__next__())#StopIteration출력
a.__next__()를 통해 iterator의 index범위 밖으로 나가게 되면, StopIteration Exception 발생하게 된다.
for문과 Iterator
파이썬의 for문은 내부적으로 Iterator를 생성하여 동작(__iter__ 메소드 이용)
ex)
리스트를 순회하는 for문
- 해당 리스트의 Iterator를 생성한 다음 __next__메소드를 이용해 순회를 도는 방식
- StopIteration을 만나기 전까지 순회를 돔
직접 iterator, iterable 만들기
__iter__메소드를 구현한 클래스를 통해 Iterable한 객체를 만들 수 있고, __next__메소드를 구현한 클래스를 통해 Iterator를 만들 수도 있다.
2개의 숫자를 입력받아 시작 값부터 종료 값까지 1씩 증가하는 Iterator를 생성
#Iterable한 객체를 만들 수 있는 클래스
class Iterable:
def __init__(self, start_number, stop_number):
self.start_number = start_number #시작 값
self.stop_number = stop_number # 종료 값
def __iter__(self):
return Iterator(self.start_number, self.stop_number)
class Iterator:
def __init__(self, start_number, stop_number):
self.start_number = start_number #시작 값
self.current_number = start_number #현재 값
self.stop_number = stop_number # 종료 값
def __next__(self):
if self.current_number < self.stop_number:
self.current_number += 1
return self.current_number
else:
raise StopIteration
test = Iterable(5,20).__iter__() #test를 iterable 인스턴스로 만든 후 __iter__메소드 호출
print(type(test))
for i in range(5,25):
try:
print(test.__next__())
except:
print("StopIteration 발생")
위의 코드는 아래와 같이 출력된다.
위의 코드를 하나의 클래스로 통합시킬 수도 있다.
#iterable과 iterator를 같이 구현한 class
class IterableAndIterator:
def __init__(self, start_number, stop_number):
self.stop_number = start_number # 시작 값 지정
self.stop_number = stop_number # 종료 값 지정
self.current_number = start_number # 현재 값 지정
def __iter__(self):
return self # 자기 자신 객체를 리턴
def __next__(self):
if self.current_number < self.stop_number:
self.current_number += 1
return self.current_number
else:
raise StopIteration
test2 = IterableAndIterator(5,20)
print(type(test2))
for i in range(5,25):
try:
print(test2.__next__())
except:
print("StopIteration 발생")
결론:
- Iterable은 내부에 __iter__메소드를 가지고 있음
- __next__ 메소드로 다음 값을 반환할 수 있으면 Iterator, 없으면 Iterable한 객체
- iterable 객체를 iter()를 통해 iterator로 만들 수 있음
- iterator는 StopIteration을 만나기 전까지 __next__메소드를 이용해 순회를 돔
- iterable객체 및 iterator를 __iter__ 및 __next__메소드를 생성하여 직접 만들 수 있다.
728x90
'language > Python' 카테고리의 다른 글
[Python] 파이썬의 여러가지 formatting 방법 다루기 (0) | 2022.03.02 |
---|---|
[Python] list comprehension이란? set, dictionary comprehension이란? 개념과 예제 (0) | 2022.03.02 |
[Python] closure(클로저)와 Decorator(데코레이터), 로깅(logging) 개념과 예제 (0) | 2022.02.28 |
[Python] lambda 함수(익명 함수) (0) | 2022.02.28 |
[Python] module, 사용법, if __name__=="__main__": ,package 개념 (0) | 2022.02.18 |
댓글