광주인력개발원 일일포스팅(메모장)
13주차 목 1116 (이터레이터, 제너레이터, 정규표현식)
Jumbo96
2023. 11. 16. 16:53
728x90
반응형
<이터레이터(Iterator)>
파이썬에서 반복 가능한 객체(클래스)를 표현하는데 사용되는 인터페이스
이터레이터는 iter()함수와 next()함수를 이용하여 반복(Iterator)을 수행함
### 클래스 정의하기
class MyIterator :
### 클래스 생성자 정의하기
def __init__(self) :
self.cuurent_value = 0
print(f"#1 (__init__) : self={self} / self.cuurent_value={self.cuurent_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.cuurent_value < 5 :
# - 반환할 변수에 current_Value의 현재값 저장
result = self.cuurent_value
# - current_Value의 현재값을 1증가
self.cuurent_value += 1
print(f"#4 : result={result} / self.cuurent_value={self.cuurent_value}")
# - result 값 반환
return result
else :
print("5 : StopIterator 예외 발생!!")
### 이터레이터는 반복이 끝나면 종류시켜야함
# - 종료시키는 방법은 강제로 오류 발생시킴
raise StopIteration
### 이터레이터 실행시키기
# - 클래스 생성하기
my_iterator = MyIterator()
#1 (__init__) : self=<__main__.MyIterator object at 0x00000170C96197D0> / self.cuurent_value=0
### 이터레이터 기능은 반복문 (for or while)을 사용해야만 작동하는 기능임
# - 최초 __iter__() 함수를 호출하고,
# - 출력 시 __next__() 함수가 한번씩 수행하면서 값을 반환받아서 출력함
# - 한번 반환된 후 메모리는 초기화 되며, 다음 반복시 다시 메모리를 사용
# ** 메모리를 효율적으로 활용할 수 있음
# 반복 수행하여 result 값 출력하기
for value in my_iterator :
print(value)
#2 (__iter__) : self=<__main__.MyIterator object at 0x00000170C96A9510>
#3 (__next__) : self=<__main__.MyIterator object at 0x00000170C96A9510>
#4 : result=0 / self.cuurent_value=1
0
#3 (__next__) : self=<__main__.MyIterator object at 0x00000170C96A9510>
#4 : result=1 / self.cuurent_value=2
1
#3 (__next__) : self=<__main__.MyIterator object at 0x00000170C96A9510>
#4 : result=2 / self.cuurent_value=3
2
#3 (__next__) : self=<__main__.MyIterator object at 0x00000170C96A9510>
#4 : result=3 / self.cuurent_value=4
3
#3 (__next__) : self=<__main__.MyIterator object at 0x00000170C96A9510>
#4 : result=4 / self.cuurent_value=5
4
#3 (__next__) : self=<__main__.MyIterator object at 0x00000170C96A9510>
5 : StopIterator 예외 발생!!
### 문자열 "Hello" 의 각 문자 하나씩 출력하는 프로그램을 작성해주세요.."hello"
for i in "Hello" :
print(i)
H
e
l
l
o
내가 한 코드
### 이터레이터 클래스 생성해서 hello 각 단어 출력하기
# - 임의 문자열을 받아서 처리
# - 임의 문자열은 외부에서 클래스 생성시 넣어준다.
class StringIterator:
def __init__(self) :
self.wd = self.get_string()
self.index = 0
def __iter__(self) :
return self
def __next__(self) :
if self.index < len(self.wd) :
result = self.wd[self.index]
self.index += 1
return result
else :
raise StopIteration
def get_string(self) :
return input("문자열 : ")
iterator = StringIterator()
for char in iterator:
print(char)
문자열 : 123456
1
2
3
4
5
6
강사님 코드
class StrintIterator :
### 클래스 생성자
def __init__(self, p_text) :
# - next함수에서 1씩 증가시키면서 반복 조건에 사용할 변수
# - p_text는 지역변수
# - text는 멤버변수
self.index = 0
# - 받아온 문자열
self.text = p_text
### 반복수행을 위한 iter 함수 정의
def __iter__(self) :
return self
### 한건 한건 처리를 위한 next 함수 정의
def __next__(self) :
if self.index < len(self.text) :
### 문자열에서 문자 하나씩 추출하기
result = self.text[self.index]
self.index += 1
return result
else :
raise StopIteration
### 이터레이터 기능 사용하기
# 반복문을 이용해서 전체 반복하기
# = 클래스 생성하기
msg = "hello"
string_iter = StrintIterator(msg)
### 반복문을 이용해서 전체 추출하기
for char in string_iter :
print(char)
h
e
l
l
o
<예제> 두개의 숫자(시작값, 종료값) 값을 이용해서 짝수값만 반환하는 이터레이터 만들기
내가 한 코
class EvenNumberIterator:
def __init__(self):
self.current = 0
def __iter__(self):
return self
def __next__(self) :
if self.current < 10:
if self.current % 2 == 0:
result = self.current
self.current += 1
return result
else:
self.current += 1
return self.__next__()
else:
raise StopIteration
num_iter = EvenNumberIterator()
for num in num_iter :
print(num)
0
2
4
6
8
강사님 코드
class EvenNumberIterator:
def __init__(self,start, end):
self.start = start
self.end = end
def __iter__(self) :
return self
def __next__(self) :
### start 부터 end 까지 무조건 반복 실행
#- i 값은 사용 안함
# - 사용하는 값은 self.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
<예제> 외부 함수를 이용해서 짝수값 추출하는 이터레이터 만들기>
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 :
### 외부함수로 짝수 of 홀수 체크
# - 짝수면 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)
<예제> 텍스트 파일의 내용을 한줄씩 반환하는 이터레이터 만들기
내가 한 코드
class FileLineIterator:
def __init__(self, filename, encoding="utf-8"):
self.filename = filename
self.file = open(filename, 'r', encoding=encoding)
def __iter__(self):
return self
def __next__(self):
line = self.file.readline()
if line:
return line
else:
self.file.close()
raise StopIteration
file_iter = FileLineIterator('./04_example.txt', encoding="utf-8")
for line in file_iter:
print(line, end='')
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢻⢷⣷⣣⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⣀⣀⣀⡀⠀⠀⠀⠀⠀⠀⠀⢏⣿⣿⡵⡀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⣠⣮⣷⣿⣿⣿⣿⣷⣄⣄⠀⠀⠀⠀⠈⢞⣿⣿⡵⡀⠀⠀⠀⠀⠀
⠀⠀⡠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⣏⢦⣤⡀⠀⠀⠀⠫⣻⣿⣾⢄⠀⠀⠀
⠀⣔⣿⣿⣿⣿⣿⣿⠿⣿⠻⢟⣿⣿⣿⣿⣿⡆⠀⠀⠀⠑⡿⣿⣯⢆⠀⠀
⢰⣸⢿⣻⢟⠃⠉⠉⠀⡠⠤⠸⣸⣿⣿⣿⡳⠁⠀⠀⠀⠀⡨⠺⠿⠇⢓⡄
⠧⠊⠁⠘⣖⣳⠠⣶⣋⡹⠁⠀⠛⣩⢻⠋⠀⠀⠀⠀⠀⢀⠇⠀⠀⠀⠀⢾⠀
⠀⠀⢠⠂⠁⠓⠒⠊⠀⡠⠤⡀⢠⠀⠚⠀⠀⠀⠀⠀⡠⠊⢀⠤⡤⣔⠩⠼⡀
⠀⠀⢇⠀⠀⢀⡠⢔⣪⠠⠖⠇⡘⠀⠀⠀⢀⠄⠒⠉⢀⠔⠁⠀⣧⢞⠮⠭⠵⡀
⠀⠀⠘⠒⠉⣾⣀⣀⠀⣀⣀⠦⠗⠹⠙⠃⠁⠀⡠⠔⡡⠔⠒⠉⡨⢴⢹⣿⣏⡆
⠀⠀⠀⠀⡸⠉⠀⠀⠁⠀⠀⠀⠀⣇⡠⡄⡶⠯⠔⠈⠀⠀⡠⠊⠀⠀⡿⣿⣿⡇
⠀⠀⠀⢀⠇⠀⠀⠀⠀⢀⣀⠤⡤⠵⠊⢸⠀⡠⠤⠤⠐⠉⠀⠀⠀⠀⣷⣿⢿⡇
⠀⠀⢀⠃⠀⢀⣀⣀⣀⣠⣀⣀⣿⠉⠉⠉⠉⠀⠀
강사님 코드
# - 파일명은 클래스가 받아서 처리
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) :
print("#1 ---------------")
### readline() 파일 정보중에 줄 하나를 가지고온다.
# - 최초 이후부터는 다음 줄이 있는지 자동으로 체크 후 가지고 온다.
# - 다음 줄이 없으면 안 가져온다.
line = self.file.readline()
print(f"#2 : line = {line}")
if line :
print(f"#3 : line = {line}")
return line.strip()
else :
print("#4 : 이터레이터 종료 ...")
self.file.close()
raise StopIteration
### 이터레이터 클래스 생성하기
file_path = "./04_example.txt"
file_iter = FileLineIterator(file_path)
### 반복해서 파일 내용 한줄씩 출력하기
for line in file_iter:
print(line)
#1 ---------------
#2 : line = 이 기상과 이 맘으로 충성을 다하여
#3 : line = 이 기상과 이 맘으로 충성을 다하여
이 기상과 이 맘으로 충성을 다하여
#1 ---------------
#2 : line = 괴로우나 즐거우나 나라 사랑하세
#3 : line = 괴로우나 즐거우나 나라 사랑하세
괴로우나 즐거우나 나라 사랑하세
#1 ---------------
#2 : line = 무궁화 삼천리 화려 강산
#3 : line = 무궁화 삼천리 화려 강산
무궁화 삼천리 화려 강산
#1 ---------------
#2 : line = 대한 사람 대한으로 길이 보전하세
#3 : line = 대한 사람 대한으로 길이 보전하세
대한 사람 대한으로 길이 보전하세
#1 ---------------
#2 : line =
#4 : 이터레이터 종료 ...
------------------------------------------------------------- 제너레이터 ----------------------------------------------------------------------------------
<제너레이터 (Generator)>
함수를 이용해서 이터레이터(반복)의 기능을 구현
이터레이터와 동일하게 호출 시점에만 메모리를 사용하고 사용이 끝나면 소멸됩니다.
반환할 때 사용하는 명령어는 return이 아닌, yield를 사용합니다.
이터레이터와 동일하게 전체 또는 next() 한건씩 출력 가능합니다.
<예제> 제너레이터 기본 문법
def simple_generator() :
### 첫번째 반환할 값
yield 1
### 두번째 반환할 값
yield 2
### 세번째 반환할 값
yield 3
### 제너레이터 전체 출력하기
# - 제너레이터에서는 함수를 객체로 인지하고 사용합니다.
# - 함수를 생성한다는 의미 또는 제너레이터 객체를 생성한다는 의미를 사용합니다.
for v in simple_generator() :
print(v)
1
2
3
<예제> 1부터 5까지의 숫자를 생성해서 반환하는 제너레이터 만들기
def number_generator() :
for i in range(1, 6, 1) :
yield i
### 전체 출력하기
### - 함수 객체 생성하기
gen = number_generator()
for num in gen :
print(num)
1
2
3
4
5
### - 함수 객체 생성하기
gen = number_generator()
### 한건씩 출력하기
try :
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))
except :
pass
1
2
3
4
5
<예제> 파일 한줄씩 일겅서 반환하는 제너레이터 만들기
### read_lines 함수 생성
def read_lines(file_path) :
### 파일처리 시 이터레이터와 다르게, with문을 사용해도 됩니다.
with open(file_path, "r", encoding = "utf-8") as file :
for line in file :
yield line.strip()
### 제너레이터 함수 생성하기
gen = read_lines("./04_example.txt")
for line in gen :
print(line)
이 기상과 이 맘으로 충성을 다하여
괴로우나 즐거우나 나라 사랑하세
무궁화 삼천리 화려 강산
대한 사람 대한으로 길이 보전하세
------------------------------------------------------------- 정규표현식 ---------------------------------------------------------------------------------
"""
<정규표현식 패턴>
* 대괄호 ([]) : 대괄호 안에 있는 문자 중에 하나라도 매치되면 추출
* 점 (.) : 앞뒤 문자 사이에 보통 주로 사용함. 하나으 ㅣ문자를 의미함
: 예시 -> a.c의 패턴인 경우 "abc", adc" .........
* 반복(*) : 앞의 문자가 0번 이상 반복될 때 추출
: 예시 -> ab*c의 패턴인 경우 "ac","abc", "abbc", "abbbbbbbbc" ...
* 반복 (+) : 앞의 문자가 1번 이상 반복될 때 추출
: 예시 -> ab+b의 패턴인 경우 "abc", "abbc", "abbbbbbbc" .........
* 반복 ({m, n}) : 앞의 문자가 최소 m번, 최대 n번 반복될 때 추출됨
: 예시 -> a{2,4}의 패턴인 경우 "aa", "aaa", "aaaa"
*반복 (^)과 끝($) : 각 문자열의 시작과 끝을 나타냄
: 예시 -> ^abc의 팬턴인 경우 "abc"로 시작하는 문자열에 대해 추출
: 예시 -> abc$의 패턴인 경우 "abc"로 끝나는 문자열에 대해 추출
* 물음표(?) : 바로 앞의 문자가 0또는 1회 나타날 수 있음을 의미함
: 예시 -> a?의 패턴인 경우 "a"Ehsms ""일 경우 추출함
* 역슬래시(\) = 이스케이프라고 읽습니다. : 특수문자를 일반 문자로 인식하게 함
* 소괄호 () = 그룹화라고 읽습니다. : 괄호 안의 패턴을 하나로 그룹으로 묶어서 처리가능
: 예시 (abc)+ 의 패턴인 경우 "abc", "abcabc", "abcabcabc"....
* [0-9] : 0에서 9까지의 숫자중 하나
* [!@#$%^&*(),.?";{}|<>] 특수 기호 중 하나
* [ㄱ-ㅎㅏ-ㅣ가-힣] : 한글 중 하나
* [a-zA-Z] : 알파벳 소문자 또는 대문자 중 하나
* \d : 숫자 중 하나
* \b : 단어의 경계를 나타냄(보통 문장의 처음과 끝에 제시함)
--> 위의 패턴은 조합해서 사용 가능
"""
<예제> 특정 문자 추출하기
### "abcdefg" 문자열에서 ade 문자에 대한 문자만 추출하기
text = "abcdefg"
### 추출할 패턴 정의하기
pattern = re.compile(r"[ade]")
### text 문자열에서 패턴에 맞는 값만 추출하기
# - findall : 임의 문자열에서 패턴에 맞는 값을 모두 찾아서 리스트 타입으로 반환합니다.
rs_text = pattern.findall(text)
print(rs_text)
['a', 'd', 'e']
<예제> 점(.) 패턴을 이용하기
text = "abcdef afceeeeazc"
pattern = re.compile(r"a.c")
rs_text = pattern.findall(text)
print(rs_text)
['abc', 'afc', 'azc']
728x90
반응형