이터러블 객체란?
파이썬에는 기본적으로 반복 가능한 객체가 있습니다. 예를들어 list, tuple, set, dict 이것 들은 다 for문을 돌릴 수 있다는 특징이 있습니다.
그러나 이러한 for문은 위 객체에만 돌릴수 있는 것은 아닙니다.
__iter__ or __next__ 매직 매소드가 구현이 되어 있느지를 통해 이터레이터를 판단할 수 있다.
또한 객체가 시퀀스이고 __lne__과 __getitem__을 모두 가졌는지 여부에 따라 for문에서 사용할 수 있는 객체를 만들수 있다.
이러터블 객체 만들기
일정 기간의 날짜를 하루 간격으로 반복하는 객체의 코드를 예시로 이해보겠습니다. 중요한 것은 __iter__, __next__ 매직 메서드를 중점으로 보자.
from datetime import timedelta, date
class DateRangeIterable:
"""Iterable class for date range"""
def __init__(self, start, end):
self.start = start
self.end = end
self._present = start
def __iter__(self):
return self
def __next__(self):
if self._present > self.end:
raise StopIteration
today = self._present
self._present += timedelta(days=1)
return today
for day in DateRangeIterable(date(2019, 1, 1), date(2019, 1, 5)):
print(day)
Output
2019-01-01
2019-01-02
2019-01-03
2019-01-04
2019-01-05
시퀀스 만들기
모든 시퀀스는 순서가 유지되고, 정수로 인덱싱하며, 길이가 있다.
예를 들자면 다음과 같은 3가지 자료구조가 존재한다.
- 문자열: 'Hello'. 문자열(string)은 문자(character)들의 시퀀스다.
- 리스트: [1, 4, 5].
- 튜플: ('GOOG', 100, 490.1).
여기서 필요한 매직 메서드는 __getitem__, __len__ 이다.
class DateRangeSequence:
"""Sequence class for date range"""
def __init__(self, start, end):
self.start = start
self.end = end
self._range = self._create_range()
def _create_range(self):
days = []
current_day = self.start
while current_day <= self.end:
days.append(current_day)
current_day += timedelta(days=1)
return days
def __getitem__(self, item):
return self._range[item]
def __len__(self):
return len(self._range)
s1 = DateRangeSequence(date(2019, 1, 1), date(2019, 1, 5))
for day in s1:
print(day)
위 이터러블 예제를 시퀀스로 구현한 형태이다.
그럼 대체 언제 시퀀스로 써야하고 언제 이터너블로 써야 할까?
이터러블 객체는 메모리를 적게 사용한다는 장점이 있다. 즉 한 번에 하나의 날짜만 보관하고 한 번에 하나씩 날짜를 생성한다. 그러나 이는 n번째 요소를 얻기 위해 n까지 도달하려고 n번 반복실행(O(n))한다. 이 문제는 전형적인 CPU와 메모리의 트레이드오프이다.
시퀀스로 구현을 하면 오히여 이터러블 보다 메모리를 더 많이 사용한다(모든 결과값을 가지고 있음) 하지만 특정 요소를 가져오는데 필요한 시간복잡도는 O(1)로 찾을 수 있다.
두가지 구현 중 어느 것을 사용할지 결정할 때 메모리와 CPU 사이의 트레이드오프를 계산해 보자,
일반적으로 이터레션이 더 좋은 선택이자만 모든 경우의 요건을 염두해야 한다.
'Python' 카테고리의 다른 글
[Python] SOLID_리스코프 치환 원칙(LSP) (0) | 2023.02.08 |
---|---|
[Python] SOLID_개방/폐쇄 원칙(OCP) (0) | 2023.02.07 |
[Python] SOLID_단일 책임 원칙(SRP) (0) | 2023.02.06 |
[Python] Context Manager 일반적으로 쓰이는 예시 (2) | 2023.01.31 |
[Python] 날짜 포맷 변경하기(strftime, strptime) (0) | 2022.03.12 |