python 알고리즘 기초4 이터레이터(Iterator)+예제
1. 0 이상 5 미만의 숫자를 나열하는 이터레이터
# 클래스 정의 하기
class MyIterator:
### 클래스 생성자 정의하기
def __init__(self):
self.current_value = 0
### 자신의 클래스를 반환하는 iter함수 정의
def __iter__(self):
return self
### 반복을 수행하는 next함수 정의
def __next__(self):
### currnet_value의 값이 5보다 작을 떄까지 반복수행
if self.current_value < 5:
# - 반환할 변수에 current_value의 현재 값 저장
result = self.current_value
# - current_value의 현재값을 1증가
self.current_value += 1
# - result값 반환
return result
else:
raise StopIteration
"이터레이터는 반복이 끝나면 종료시켜야 함, 종료시키는 방법은 강제로 오류 발생시킴"
### 이터레이터 실행 시키기
# - 클래스 생성하기
my_iterator = MyIterator()
for value in my_iterator:
print(value)
결과 :
0
1
2
3
4
이터레이터 기능은 반복문 (for 또는 while)을 사용해야만 작동하는 기능이다.
최초 __ilter__() 함수를 호출하고, 출력 시 __next__() 함수가 한 번씩 수행하면서 값을 반환받아서 출력함.
한번 반환된 후 메모리는 초기화되며, 다음 반복 시 다시 메모리 사용
반복 수행하여 result값 출력하기
이터레이터를 사용하는 가장 큰 이유는 메모리를 효율적으로 사용할 수 있다는 것이다.
중간중간 작동하는 순서를 보기 위해 프린트함수를 써서 확인해 보겠다.
class MyIterator:
def __init__(self):
self.current_value = 0
print(f"#1(__init__) : self={self} / self.current_value={self.current_value}")
def __iter__(self):
print(f"#2(__iter__) : self={self}")
return self
def __next__(self):
print(f"#3(__next__) : self={self}")
if self.current_value < 5:
result = self.current_value
self.current_value += 1
print(f"#4 : resutl={result} / self.current_value={self.current_value}")
return result
else:
print("#5 : StopIteration 예외발생!")
raise StopIteration
my_iterator = MyIterator()
결과 : #1(__init__) : self=<__main__. MyIterator object at 0x0000021 C0442 B410> / self.current_value=0
결과를 출력하는 방법으로 한 번에 모든 값을 출력하는 법과 각각의 데이터로 뽑는 두 가지 방법이 있다.
*1번 방법 for문을 사용하여 한번에 출력
for value in my_iterator:
print(value)
결과 :
#2(__iter__) : self=<__main__. MyIterator object at 0x0000021 C0442 B410>
#3(__next__) : self=<__main__. MyIterator object at 0x0000021C0442B410>
#4 : resutl=0 / self.current_value=1
0
#3(__next__) : self=<__main__.MyIterator object at 0x0000021C0442B410>
#4 : resutl=1 / self.current_value=2
1
#3(__next__) : self=<__main__.MyIterator object at 0x0000021C0442B410>
#4 : resutl=2 / self.current_value=3
2
#3(__next__) : self=<__main__.MyIterator object at 0x0000021C0442B410>
#4 : resutl=3 / self.current_value=4
3
#3(__next__) : self=<__main__.MyIterator object at 0x0000021C0442B410>
#4 : resutl=4 / self.current_value=5
4
#3(__next__) : self=<__main__.MyIterator object at 0x0000021C0442B410>
#5 : StopIteration 예외발생!
*2번 방법 각각의 데이터로 뽑기
try:
print(next(my_iterator))
print(next(my_iterator))
print(next(my_iterator))
print(next(my_iterator))
print(next(my_iterator))
print(next(my_iterator))
except:
print("이터레이터가 종료되었음.")
결과 :
#3(__next__) : self=<__main__. MyIterator object at 0x0000021 C04704450>
#4 : resutl=0 / self.current_value=1
0
#3(__next__) : self=<__main__. MyIterator object at 0x0000021 C04704450>
#4 : resutl=1 / self.current_value=2
1
#3(__next__) : self=<__main__.MyIterator object at 0x0000021C04704450>
#4 : resutl=2 / self.current_value=3
2
#3(__next__) : self=<__main__.MyIterator object at 0x0000021C04704450>
#4 : resutl=3 / self.current_value=4
3
#3(__next__) : self=<__main__.MyIterator object at 0x0000021C04704450>
#4 : resutl=4 / self.current_value=5
4
#3(__next__) : self=<__main__.MyIterator object at 0x0000021C04704450>
#5 : StopIteration 예외발생!/
이터레이터가 종료되었음.
자바의 try cath같이 파이썬에서는 try excep를 사용하여 예외 처리를 한다.
2. 두 개의 숫자(시작값, 종료값) 값을 이용해서, 짝수값만 반환하는 이터레이터
class EvenNumberIterator:
def __init__(self, start, end):
self.start = start
self.end = end
def __iter__(self):
return self
def __next__(self):
### start 부터 end까지 무조건 반복 샐행
# - i 값은 사용안함
# - 사용하는 값은 sel.start만 사용
for i in range(self.start, self.end, 1):
### self.start가 짝수인지 체크
if self.start%2 == 0:
### 반환할 함수에 저장
result = self.start
# - self.start값은 1씩 증가
self.start += 1
# - 반환하기 : 반환하면 for 문은 종료됨
return result
### 짝수가 아니라면
else:
# - 1증가만 시키고 반보글 계속 수행
self.start += 1
### for문을 이용한 경우에는, 이터레이터 반복 종료후 맨 마지막에 추가
raise StopIteration
even_iter = EvenNumberIterator(1, 10)
for even in even_iter:
print(even)
결과 :
2
4
6
8
3. 외부 함수를 이용해서 짝수값을 추출하는 이터레이터
class EvenNumberIterator:
### 클래스 생성자 정의
def __init__(self, start, end, func):
# - 시작값
self.start = start
# - 종료값
self.end = end
# - 외부함수
self.func = func
### 반복을 위한 이터레이터 함수 정의
def __iter__(self):
return self
### 반복 결과값을 처리할 함수 정의
def __next__(self):
### 시작부터 종료까지 while 반복
while self.start <= self.end:
### 외부함수로 짝수 or 홀수 체크
# - 짝수면 True 홀수면 False
if self.func(self.start):
result = self.start
self.start += 1
return result
else:
self.start += 1
### 이터레이터 종료하기
raise StopIteration
### 짝수와 홀수로 판별하는 외부함수 정의하기
def is_even(num):
return num%2 == 0
### 이터레이터 클래스 생성
even_iter = EvenNumberIterator(1, 10, is_even)
### 이터레이터 반복 수행하기
for even in even_iter:
print(even)
결과 :
2
4
6
8
10
4. 택스트 파일의 내용을 한 줄씩 변환하는 이터레이터
class FilelineIterator:
def __init__(self, file_path):
self.file_path = file_path
self.file = open(file_path, 'r', encoding = 'UTF-8')
def __iter__(self):
return self
def __next__(self):
line = self.file.readline()
if line:
return line.strip()
else:
self.file.close()
raise StopIteration
### 이터레이터 클래스 생성하기
file_path = "./04_example.txt"
file_iter = FilelineIterator(file_path)
### 이터레이터 클래스 생성하기
file_path = "./04_example.txt"
file_iter = FilelineIterator(file_path)
결과 :
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
sssssssssssssssssssssssssssssssssssssss
ddddddddddddddddddddddddddddddddddddddd
fffffffffffffffffffffffffffffffffffffff
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq