이터레이터(Iterator)는 파이썬에서 순회 가능한 객체(iterable)에서 값을 하나씩 가져오는 객체.
이터레이터는 __iter__()와 __next__() 메서드를 구현한 객체로,
iter() 함수를 사용하여 이터레이터 객체를 생성하고,
next() 함수를 사용하여 다음 값을 가져올 수 있다.
- 파이썬에서 반복 가능한 객체(클래스)를 표현하는데 사용되는 인터페이스
### 클래스 정의하기
class MyIterator:
### 클래스 생성자 정의하기
def __init__(self):
self.current_value=0
print ( f'#1 (__init__): self = {self} / self.current_value={self.current_value}')
### 자신의 클래스를 반환하는 iter함수 정의
# 반복문을 사용할때 작동하는 함수
def __iter__(self):
print(f'#2 (__iter__) : self = {self}')
return self
### 반복을 수행하는 next 함수 정의
def __next__(self):
print(f'#3 (__next__) : self = {self}')
### current_value의 값이 5보다 작을 때 까지 반복 수행
if self.current_value <5:
# - 반환할 변수에 current_value의 현재 값 지정
result = self.current_value
# - current_value의 현재 값을 1증가
self.current_value +=1
print(f'#4 result = {result} / self.current_value = {self.current_value}')
# - result 값 반환
return result
else:
print("#5 : StropIteration 예외 발생!!")
### 이터레이터는 반복이 끝나면 종료시켜야 함
# - 종료시키는 방법은 강제로 오류 발생시킴
raise StopIteration
### 이터레이터 실행시키기
# 클래스 생성하기
my_iterator = MyIterator()
#1 (__init__): self = <__main__.MyIterator object at 0x000001DDEF288B90> / self.current_value=0
### 이터레이터 기능은 반복문(for or while)을 사용해야만 작동하는 기능함
# - 최초 __iter__() 함수를 호출하고
# - 출력시 __next__() 함수가 한번씩 수행하면서 값을 반환받아서 출력함
# - 한번 반환된 후 메모리는 초기화되며 다음 반복시 다시 메모리 사용
# ** 메모리를 효율적으로 활용할 수 있음ㄲ
#반복 수행하여 result값 출력하기
for value in my_iterator:
print (value)
#2 (__iter__) : self = <__main__.MyIterator object at 0x000001DDEF06A4D0>
#3 (__next__) : self = <__main__.MyIterator object at 0x000001DDEF06A4D0>
#4 result = 0 / self.current_value = 1
0
#3 (__next__) : self = <__main__.MyIterator object at 0x000001DDEF06A4D0>
#4 result = 1 / self.current_value = 2
1
#3 (__next__) : self = <__main__.MyIterator object at 0x000001DDEF06A4D0>
#4 result = 2 / self.current_value = 3
2
#3 (__next__) : self = <__main__.MyIterator object at 0x000001DDEF06A4D0>
#4 result = 3 / self.current_value = 4
3
#3 (__next__) : self = <__main__.MyIterator object at 0x000001DDEF06A4D0>
#4 result = 4 / self.current_value = 5
4
#3 (__next__) : self = <__main__.MyIterator object at 0x000001DDEF06A4D0>
#5 : StropIteration 예외 발생!!
### 이터레이터 실행시키기
# 클래스 생성하기
my_iterator = MyIterator()
#1 (__init__): self = <__main__.MyIterator object at 0x000001DDEF816410> / self.current_value=0
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 0x000001DDEF816410>
#4 result = 0 / self.current_value = 1
0
#3 (__next__) : self = <__main__.MyIterator object at 0x000001DDEF816410>
#4 result = 1 / self.current_value = 2
1
#3 (__next__) : self = <__main__.MyIterator object at 0x000001DDEF816410>
#4 result = 2 / self.current_value = 3
2
#3 (__next__) : self = <__main__.MyIterator object at 0x000001DDEF816410>
#4 result = 3 / self.current_value = 4
3
#3 (__next__) : self = <__main__.MyIterator object at 0x000001DDEF816410>
#4 result = 4 / self.current_value = 5
4
#3 (__next__) : self = <__main__.MyIterator object at 0x000001DDEF816410>
#5 : StropIteration 예외 발생!!
이터레이터가 종료되었습니다.
print (iter(my_iterator))
#2 (__iter__) : self = <__main__.MyIterator object at 0x000001DDEF816410>
<__main__.MyIterator object at 0x000001DDEF816410>
for i in range(len("hello")):
print("hello"[i])
h
e
l
l
o
# <예제 문자열을 전달 받아서 문자 하나씩 추출하여 반환하는 이터레이터 생성>
### 문자열을 "Hello"의 각 문자 하나씩 출력하는 프로그램을 작성해주세요
# 임의의 문자열을 받아서 처리
# 임의의 문자열의 외부에서 클래스 생성시 넣어줍니다.
class StringIterator:
def __init__(self, x):
self.my_string = x
self.index = 0
def __iter__(self):
return self
def __next__(self):
if self.index <len(self.my_string):
chr = self.my_string[self.index]
self.index +=1
return chr
else:
print("출력종료")
raise StopIteration
### 이터레이터 기능 사용하기
# 반복문을 이용해서 전체 반복하기
# 클래스 생성하
string_iterator = StringIterator(input("출력할 문자를 입력하세요"))
for value in string_iterator:
print(value)
출력할 문자를 입력하세요 파이썬
파
이
썬
출력종료
my_iterator = iter(input("출력할 작성"))
# 이터레이터 사용
for value in my_iterator:
print(value)
출력할 작성 파이썬
파
이
썬
from memory_profiler import profile
### 주피터노트북에서는 아래 로드 처리 해야함
%load_ext memory_profiler
### 이터레이터 클래스 생성하기
class SimplIterator :
def __init__(self, limit):
##반복 범위를 지정할 값(반복의 끝 값)
self.limit = limit
###반복 시작값
self.current = 0
def __iter__(self):
return self
def __next__(self):
if self.current < self.limit:
self.current += 1
return self.current
else:
raise StopIteration
### 데코레이터 함수 정의하기
### 이터레이터를 사용하지 않고 메모리 체크하기
@profile
def no_iterator(limit):
data = [i for i in range(1, limit+1)]
### 이터레이터를 사용해서 메모리 체크하기
@profile
def yes_iterator(limit):
data = SimplIterator(limit)
for item in data:
### 반복만 하고 별도 출력은 안함
pass
### 데코레이터 함수 호출하기
limit = 1000000
try:
%memit no_iterator(limit)
%memit yes_iterator(limit)
except:
pass
ERROR: Could not find file C:\Users\user\AppData\Local\Temp\ipykernel_13156\1496161889.py
peak memory: 128.84 MiB, increment: 27.24 MiB
ERROR: Could not find file C:\Users\user\AppData\Local\Temp\ipykernel_13156\1496161889.py
peak memory: 104.16 MiB, increment: 0.00 MiB
일반 반복문의 경우 128, 반복시 마다 메모리가 27만큼 추가사용
이터레이터 사용의 경우 104!! 반복시에는 메모리가 추가사용되지 않는다.
# <예제> 두 개의 숫자(시작값, 종료값) 값을 이용해서 , 짝수값만 반환하는 이터레이터 만들기
### 이터레이터 클래스 : EvenNumberIterator
class EvenNumberIterator:
def __init__(self,start,end):
self.start = start
self.end = end
def __iter__(self):
return self
def __next__(self):
# for x in range(self.start,self.end+1):
# if self.start % 2 == 0:
# result = self.start
# self.start += 1
# return result
# else:
# self.start += 1
# raise StopIteration
# if self.start <= self.end:
if self.start <= self.end:
if self.start % 2 == 0 :
result = self.start
self.start += 1
return result
else:
self.start += 1
return self.__next__()
else:
raise StopIteration
startnum = 1
endnum = 10
even_iter = EvenNumberIterator(startnum,endnum)
for v in even_iter:
print(v)
2
4
6
8
10
try:
print (next(even_iter))
print (next(even_iter))
print (next(even_iter))
print (next(even_iter))
print (next(even_iter))
print (next(even_iter))
print (next(even_iter))
except:
print ("이터레이터가 종료되었습니다.")
2
4
6
8
10
이터레이터가 종료되었습니다.
# < 예제 외부 함수를 이용해서 짝수값 추출하는 이터레이터 만들기>
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 value in even_iter:
print (value)
2
4
6
8
10
<예제> 텍스트 파일의 내용을 한줄씩 반환하는 이터레이터 만들기
### 클래스 이름 : FileLineIterator
# 파일명은 외부에서 클래스에 주면된다.
class FileLineIterator:
def __init__(self, file_name):
self.file_name= file_name
self.file = open(self.file_name,'r', encoding="utf-8")
def __iter__(self):
return self
def __next__(self):
result = self.file.readline()
print(f"#2 : line = {result}")
if result:
print(f"#3 : line = {result}")
return result
else:
print(f"#4 : 이터레이터 종료...")
self.file.close()
raise StopIteration
lead = FileLineIterator("04_example.txt")
lead2 = FileLineIterator("05_example.txt")
for value in lead:
print(value)
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣤⡴⠒⠚⣻⠇⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠓⠒⠒⠒⠒⢤⣤⠴⠚⠉⠀⡸⠁⣠⠞⠁⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⡆⠀⠀⣠⠖⠋⠀⠀⠀⠀⢀⡧⠞⠣⠤⣀⡀⠀⠀⠀⠀
⢀⣤⠔⠒⠚⣏⠉⠉⠉⠉⠉⠉⠉⠒⠒⠲⠤⠒⠋⠉⠉⠉⠉⠉⠒⠒⠻⢴⠋⠀⠀⠀⠀⠀⣠⠔⠋⠀⠀⠀⠀⠀⠉⠑⠲⢤⡀
⠈⠙⠒⠤⢄⣘⣦⡀⠀⠀⠀⠀⠀⠀⡔⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣤⠤⠖⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡼
⠀⠀⠀⠀⠀⠀⠈⢉⣿⣗⡒⠒⠒⡾⠁⣠⣶⠒⡆⠀⠀⠀⠀⠀⠀⠀⣀⣄⡀⠀⢳⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠞⠀
⠀⠀⠀⠀⠀⠀⢠⡎⠀⠀⠙⢦⣀⠇⠀⠻⣼⡿⠁⠀⠀⢠⡄⠀⠀⠸⣷⣼⣷⠀⢸⣆⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⠋⠀⠀
⠀⠀⠀⠀⠀⠀⠈⣏⠀⠀⠀⠀⡿⠖⠲⣄⠀⠀⣤⡀⢀⣤⣀⠀⠀⢀⠈⠋⠁⠀⢸⣿⡉⠓⠦⣀⡀⠀⠀⠀⠀⢀⡴⠁⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⢹⡀⠀⠀⠀⡇⠀⠀⣸⠀⠀⢸⣯⠟⠛⠛⢿⣿⠋⠀⢰⠟⠉⠹⡇⢷⠀⠀⠀⠉⠓⠦⣄⣠⠎⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⣇⠀⠀⠀⠹⡦⠴⠋⠀⠀⠀⢹⡄⠀⢀⡼⠁⠀⠀⣇⠀⠀⢠⡇⣀⣧⠀⠀⠀⠀⠀⠀⠁⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠸⡄⠀⠀⠀⠙⢆⠀⠀⠀⠀⠀⠹⠤⠋⠀⠀⠀⠀⠈⠓⡶⠋⠙⠳⠤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⡄⠀⠀⠀⠀⠑⠶⠀⠀⠀⠀⠀⠀⠀⠀⠀⣤⠖⠋⠀⠀⠀⠀⠀⠀⠉⠲⢤⡀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣶⠆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⡀⠀⠀⠀⠀⠀⠀⢀⣷⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣧⠤⣤⠤⠴⠒⠒⠚⠁⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢧⡰⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⡁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡞⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢧⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡸⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣿⡆⢀⣠⠤⠒⠒⠒⠂⠀⠀⠐⠒⠒⠒⠒⠲⢦⡀⠀⠳⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⣿⡟⠋⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠑⠒⠾⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
for value in lead2:
print(value)
⠀ ⠀⠀⠀⠀⠀ ⠀⣀⣀⣀⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⣿⣿⣿⣿⣿⣿⣿⣶⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⣾⣿⣿⣿⣿⣿⣿⣿⢿⣿⣿⣿⣿⣿⣷⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⢀⣿⣿⡿⠟⠙⠛⠛⠁⠀⠈⠙⢿⣿⣿⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⢸⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⣼⣿⣿⠀⠀⠊⣉⡙⠆⣤⣞⡉⠃⢸⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⣻⣿⣿⡆⠀⠀⠈⢁⣠⣈⡛⠁⠀⢸⣿⡟⠀⠀⢀⢀⠀⠀⠀
⠀ ⠀⠀⠀⢰⣿⣿⣿⣿⠃⠀⠀⠰⣯⣼⣿⣿⠀⠀⠀⢻⣿⣦⡀⡏⠉⠑⡄
⠀⠀⠀⣾⣿⣿⣿⡇⠀⠀⠀⠀⠙⠿⠿⠋⠀⠀⠀⠈⣿⣿⡃⢱⠀⠀⡇⠀⠀
⠀⠀⠀⢸⣿⣿⣿⣷⠤⣄⣀⣀⣀⠀⠀⠀⠀⢀⡠⠾⠿⠟⢡⠃⠀⠀⡇⠀⠀
⠀⠀⠀⠈⠙⠓⠀⠀⠀⣴⣿⣧⣼⣽⣷⣾⣟⠉⠉⠒⠒⠊⠀⠀⠀⡇⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣧⡀⠀⠀⠀⠀⣠⠎⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⢀⠜⣽⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣀⡤⠖⠋⠀⠀
그런데 한줄씩 읽은 값이 공백이 생기면서 그림 모양이 깨지는 현상이 발생합니다.
그래서 공백을 제거하는 strip()함수를 사용해줍니다.
return result.strip()
'파이썬' 카테고리의 다른 글
정규표현식(Regrlar_Expression)_프로그램 (0) | 2023.11.16 |
---|---|
메모리 절약을 위한 제너레이터 사용 (0) | 2023.11.16 |
클로저와 데코레이터 (3) | 2023.11.14 |
유니코드 짧은 (1) | 2023.11.14 |
도서 입고/대출반납 관리를 위한 키오스크 파이썬 프로그램 실습 (4) | 2023.11.13 |