Python to AI

Iterator, Generator

최 수빈 2024. 11. 14. 15:37

 

Iterable(반복 가능한 객체)

하나씩 차례대로 값을 꺼내올 수 있는 객체

=> list, tuple, str, dict

for 루프에서 반복할 수 있으며, 내부적으로는 __iter__()메서드를 통해 이터레이터 반환

 

numbers = [1,2,3,4,5]
for num in numbers:
	print(num)
numbers = [1,2,3]
iterator = iter(numbers) #리스트로부터 이터레이터 생성
print(next(iterator))
print(next(iterator))
print(next(iterator))

#1
#2
#3

 

__next__() 매직메서드를 호출할 때마다 다음 요소 반환

 

더 이상 꺼낼 요소가 없으면 StopIteration 예외 발생

 

__iter__() : 이터레이터 객체 자신을 반환하는 메서드__next__(): 이터레이터 다음 요소를 반환하는 메서드

 

#이터레이터 구현

class MyIterator:
	def __init__(self, data):
    	    self.data = data
            self.index = 0
        
	def __iter__(self):
    	    return self

	def __next__(self):
    	    if self.index < len(self.data):
        	result = self.data(self.index):
                self.index += 1
                return result
            else:
        	raise StopIteration
            
            
#이터레이터 사용
my_iter = MyIterator([1,2,3])
for iterm in my_iter:
	print(item)

 

Generator (제너레이터)

 

이터레이터를 생성하는 특별한 함수

yield 키워드를 사용해 값을 하나씩 반환

제너레이터는 모든 값을 한꺼번에 메모리에 올리지 않고, 필요할 때마다 값을 생성 => 메모리 효율성이 높음

 

yield가 호출될 때마다 함수의 상태가 유지, 다음 호출 시 그 상태로부터 실행이 재개

제너레이터는 호출 시 객체를 반환, 그 객체는 이터레이터'처럼' 동작

 

*장점 :

메모리 효율성 - 모든 값을 한 번에 생성하지 않고, 필요할 때만 값을 생성 => 메모리 사용 줄임

느린 계산(계산 지연) - 결과를 즉시 계산하지 않고, 필요할 때 계산을 지연시킴 => 큰 데이터 처리, 연속적인 계산이 필요한 작업에 유용

 

 

#제너레이터 함수 특징 예시

def simple_generator():
	yield 1
	yield 2
	yield 3

gen = simple_generator()

print(next(gen())
print(next(gen())
print(next(gen())

#1
#2
#3
#제너레이터 사용 예시

def fibonacci(n): #피보나치 수열 생성 제너레이터 정의
    a, b = 0, 1 #a와 b의 초기값 0, 1로 설정 (a는 현재 항, b는 다음 항)
    for _ in range(n): #n번 반복 (수열의 항 개수)
    	yield a #현재 a값을 호출한 쪽에 반환하고, 다음 실행을 위해 함수 상태를 유지
        a, b = b, a + b #a는 b로, b는 a + b로 업데이트
        
#피보나치 수열 생성
for num in fibonacci(10): #for loop 사용, 10개 피보나치 수 생성
	print(num)
    
#0
#1
#1
#2
#3
#5
#8
#13
#21
#34