[20250124] 파이썬 프로그래밍 - 고급함수
수업 목표
- 이터레이터 개념을 이해할 수 있다.
- 이터레이터의 값을 for문을 사용해 확인할 수 있다.
- 제너레이터를 활용하여 이터레이터를 생성할 수 있다.
- 제너레이터 생성 방법 2가지를 이해할 수 있다.
1. 이터레이터
- next 함수 호출 시 계속 그 다음 값을 리턴하는 객체
* 리스트는 이터러블한 것이고 이터레이터 객체는 아님. next(리스트)에서 에러가 뜨는 것으로 확인할 수 있음
* 이터러블한 것은 iter()로 이터레이터로 변환 가능. e.g. iter(리스트)
- next로 더 이상 리턴할 값이 없다면 StopIteration 예외 발생
- for문을 이요하면 next를 사용할 필요 없이 자동으로 값을 호출할 수 있음
- 한 번 읽으면 다시 값을 읽을 수 없음
클래스로 이터레이터 생성
- 클래스에 __iter__와 __next__라는 2개의 메서드를 구현하여 생성 가능
class MyIterator():
def __init__(self, data):
self.data = data
self.position = 0
def __iter__(self):
return self
def __next__(self):
if self.position >= len(self.data):
raise StopIteration
result = self.data[self.position]
self.position += 1
return result
- __iter__ 메서드를 구현하면 해당 클래스로 생성한 객체는 반복 가능한 객체
- __iter__ 메서드는 반복 가능한 객체를 리턴해야 하며, 보통 클래스의 객체를 의미하는 self를 리턴
- __iter__ 메서드 구현 시 반드시 __next__ 함수 구현해야 함
- __next__ 메서드는 반복 가능한 객체의 값을 차례대로 반환하는 역할을 수행
- __next__ 메서드는 for문을 수행하거나 next 함수 호출 시 수행
2. 제너레이터
- 이터레이터 생성 함수
- 제너레이터로 생성한 객체는 이터레이터와 마찬가지로 next 함수 호출 시 그 값을 차례대로 획득 가능
- 제너레이터에서는 차례대로 결과를 반환하고자 return 대신 yield 키워드 사용
def mygen():
yield 'a'
yield 'b'
yield 'c'
def mygen():
for i in range(1,1000):
result = i * i
yield result
gen = mygen()
print(next(gen))
제너레이터 생성 방법
- 제너레이터 표현식(generator expression) 활용 생성
- 튜플을 컴프리헨션 형태로 생성
- 컴프리헨션(comprehension): 파이썬의 자료구조(list, dictionary)에 데이터를 좀 더 쉽고 간결하게 담기 위한 문법
e.g. gen = (i*i for i in range(1, 10000))
- yield할 값이 더 이상 없으면 동일하게 StopIteration 예외 발생
* 간단한 상황에서 사용하면 좋고, 조금 더 복잡한 행동을 구현해야 할 때 클래스 활용
* 필요한 경우에만 호출하여 사용할 때 제너레이터가 유용함
느긋한 계산법 (lazy evaluation)
import time
def longtime_job():
print("job start")
time.sleep(1)
return "done"
list_job = [longtime_job() for _ in range(5)]
for x in list_job:
print(x)