[python] generator (제너레이터)

gunny·2024년 3월 5일
0

Python

목록 보기
7/29

Generator

먼저 generator에 대해 작성하기에 앞서, 참고해서 공부하고 있는 사이트에서 이터레이터를 언급하고 있다.

iterator(이터레이터, 반복자)

프로그래머가 컨테이너, 특히 목록을 탐색할 수 있게 해주는 객체

  • 이터레이터는 순회를 수행하고 컨테이너의 데이터 요소에 대한 엑세스는 제공하지만, 반복(iteration)은 수행하지 않는다.
  • 여기서 iterable(반복가능한 객체), 반복자(Iterator), 반복(Iteration) 이 나오는데, 이전 게시물에서 한 번 정리를 했었다.

https://velog.io/@heyggun/python-이터레이터-iterator-iter-getitem

무튼 짧게 정리하고 가자면, Iterable(순회 가능한 객체, 반복 가능한 객체) 는 iterator를 반환하고 인덱스를 취할 수 있는__iter__, __getitem__ 메소드가 정의된 파이썬의 객체이다.
iterator를 제공할 수 있는 객체라고 보면된다.

  • iterator(반복자)는 __next__ 메소드가 정의된 객체이다.
  • Iteration(반복) 은 배열과 같은 자료 구조에서 item, 원소를 가져오는 과정이다.

그렇다면 본격적으로 제너레이터에 대해서 알아보자.

generator(이하 제너레이터)

  • 제너레이터는 iterator(반복자)를 생성해주는 함수이다.
  • yield 키워드를 사용한다.
  • 제너레이터는 이터레이터이지만 단 한 번만 반복한다.
    메모리에 모든 값을 저장하지 않기 때문에 값을 사용할 때 즉시 생성한다.
    for loop를 사용하거나 반복하는 함수나 구조에 생성된 값들을 전달하여 반복을 통해 사용한다.
  • 대부분 제너레이터 들은 함수로 구현된다. 그러나 값을 반환하지 않고 yield(산출)될 뿐이다.

generator 특징

  • 모든 제너레이터는 Iterator 이면서 동시에 Iterable 한객체라는 것이다.
    제너레이터가 __iter____next__ 메서드를 내부적으로 구현하여 반복 가능한 객체로 동작할 수 있게 만들어 졌기 때문이다.

간단한 예로 0부터 시작해 무한히 증가하는 값을 생성하는 제너레이터 함수 코드를 보자면

	
def infinite_generator():
	i = 0
    while True:
    	yield i
        i+=1
 
# 제너레이터 객체 생성
gen_obj = infinite_generator()

# 반복 가능한지 확인
print(isinstance(gen_obj, Iterable)) # output True

# 값을 얻기 위해 반복
print(next(gen_obj)) # output 0
print(next(gen_obj)) # output 1
print(next(gen_obj)) # output 2
        
  • 여기서 infinite_generator 함수에서 생성된 gen_obj는 'Iterator' 이면서 'Iterable' 이다. 즉, for loop나 iter() 함수를 통해 순회가 가능하다는 의미이다.
  • next() 함수를 통해 제너레이터로부터 값도 얻고 있다.

따라서 모든 generator는 iterator로 iterable 순서가 지정된다는 것은
제너레이터는 반복가능한 객체이며 내부에서 __iter__, __next__를 구현하여 순회가능하고
next() 함수로 값을 생성한다는 의미이다.

generator의 사용

제너레이터는 모든 결과물들을 메모리에 저장하지 않으면서 동시에 많은 양의 결과 셋을 계산해야 할때 유용하다.

  • 주로 대용량 데이터를 처리하거나 연속적인 이벤트를 생성할때 사용한다.

[1] 로그 파일을 읽어오고 특정 조건을 만족하는 로그를 출력할 때 사용


def read_logs(log_file_path):
	with open(log_file_path, 'r') as file:
    	for line in file:
        	yield line.strip()
            
def filter_logs(logs, keyword):
	for log in logs:
    	if keyword in log:
        	yield log
            
def process_logs(logs):
	for log in logs:
    	yield f"Processed log: {log}"
        
# 로그 파일 경로 지정
log_file_path = 'example.log'

# 로그 파일을 읽어오는 제너레이터 생성
logs_generator = rea_logs(log_file_pth)

# 특정 키워드를 포함하는 로그를 필터링하는 제너레이터 생성
filtered_logs_generator = filter_logs(logs_generator, keyword='error')

# 로그를 가공하는 제너레이터 생성
process_logs_generator = process_logs(filtered_logs_generator)

# 최종적으로 제너레이터를 사용하여 출력

for processed_log in process_logs_generator:
	print(processed)log)
  • 위 코드에서 'read_logs' 함수는 로그 파일을 한 줄씩 읽어오는 제너레이터를 생성한다.
    그리고 'filter_logs'는 특정 키워드를 포함하는 로그만을 필터링하는 제러레이터를 생성한다.
    마지막으로 'process_logs' 함수는 로그를 가공하거나 다른 작업을 수행하는 제너레이터를 생성한다.
    이러한 제너레이터를 조합하여 로그 파일을 필터링하고 가공하는 프로세스를 구현한다.

[2] 데이터베이스에서 대량의 데이터를 읽어와서 처리할 때 사용

  • 파일이나 데이터베이스로부터 대용량 데이터를 읽어오는 상황이라고 가정했을 때
import random

def generator_large_data(size):
	for _ in range(size):
    	yield random.randint(1, 1000)
 
def process_large_data(data):
	for value in data:
    	yield f"Processed data : {value}"
        
# 대량의 데이터를 생성하는 제너레이터
large_data_generator = generator_large_data(1000000)

# 데이터를 가공하는 제너레이터 생성
processed_data_generator = process_large_data(large_data_generator)

# 최종적으로 제너레이터를 사용해서 출력(상위 5개)
for _ in range(5):
	processed_data = next(processed_data_generator)
    print(processed_data)
  • 위 코드에서 'generate_large_data' 함수로 가상의 대량 데이터를 생성하는 제너레이터를 생성하고, 'process_large_data' 함수는 받은 데이터를 가공하거나 다른 작업을 수행하는 제너레이터이다.
    위에서는 무작위로 생성한 가상 데이터를 사용했지만, 실제 서비스에서는 데이터베이스에서 데이터를 읽어오는 방식을 사용할 수 있다.

참고사이트

[1] https://ddanggle.gitbooks.io/interpy-kr/content/ch3-generators.html\

profile
꿈꾸는 것도 개발처럼 깊게

1개의 댓글

comment-user-thumbnail
2024년 9월 24일

A generator in Python is a special type of iterator geometry dash, but with its own distinct advantages and use cases. Generators allow you to iterate over data lazily, meaning that instead of loading the entire dataset into memory at once, you can generate each item on the fly.

답글 달기