ROKEY

[20250124] 파이썬 프로그래밍 - 고급함수

kode-daks 2025. 1. 24. 16:27

수업 목표

- 이터레이터 개념을 이해할 수 있다.

- 이터레이터의 값을 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)