[python] Generators

happiyoung_·2024년 10월 8일

python

목록 보기
1/1

intro

파이썬 웹 프레임워크 Fastapi를 공부하던 도중에 generator를 만드는 과정이라는 말을 듣고 궁금해져 공부해보려고 한다.

generator?

함수가 iterator 와 같이 동작하도록 선언하는 함수들

iterator와 같이 동작한다는 말은 또 무슨말인가?
iterator 편을 참고하자.

iterator(list type) VS generator

다시 generator로 돌아와, 예시를 통해 이해해보려고 한다.

def first_n(n):
	'''Build and return a list'''
	num, nums = 0, []
	while num < n:
		nums.append(num)
		num += 1
	return nums

sum_of_first_n = sum(first_n(1000000))

위의 코드에서는 1000000개의 숫자로 이루어진 list가 만들어지고 메모리는 이렇게 큰 양의 숫자를 견딜 수 없을 것이다.

generator 패턴

위의 예시를 generator 패턴으로 작성해보자.

# Using the generator pattern (an iterable)
class first_n(object):
	def __init__(self, n):
		self.n = n
		self.num = 0

	def __iter__(self):
		return self

	# Python 3 compatibility
	def __next__(self):
		return self.next()
        
	def next(self):
		if self.num < self.n:
			cur, self.num = self.num, self.num+1
			return cur
		raise StopIteration()
sum_of_first_n = sum(first_n(1000000))

동작은 같지만, 생성자가 많아 복잡하게 얽혀있게 보인다.
따라서 파이썬에서는 간단하게 generator function을 작성할 수 있도록 shortcut을 제공한다.

# a generator that yields items instead of returning a list
def firstn(n):
	num = 0
	while num < n:
		yield num
		num += 1

sum_of_first_n = sum(firstn(1000000))

yield 를 사용한 것을 주목해야 한다.

실험

동일한 결과 값을 제공하는 함수 두개가 있다.
function1

import time

def abc():
  alphabets = []
  for c in "ABC":
    time.sleep(1)
    alphabets.append(c)
  return alphabets

for c in abc():
  print(c)

function2

import time

def abc():
  for c in "ABC":
    time.sleep(1)
    yield c
    
for c in abc():
  print(c)

비교 분석

  • function1의 경우 3초가 흐른뒤에 A,B,C가 한번에 똬다닥 출력된다.
  • function2의 경우 for문이 돌때마다 1초 경과후에 A가 B가 C가 출력된다.
    결과적으로, 문자열의 길이가 길어질때 function1과 같은 로직은 n시간 만큼이 걸리지만 function2와 같은 로직은 조회시 걸리는 시간 1초 뿐이다.

generator 장점

결과값을 하나씩 메모리에 올려놓기 때문에 성능상의 이점이 있다.

  • 대용량을 파일을 읽는 경우
  • 스트림 데이터를 처리하는 경우
    위와 같은 상황에서 효율적인 프로그램을 작성할 수 있다.

outro

iterator를 사용하려는데 데이터의 양이 너무 많거나 메모리가 부족한 경우에 generator를 사용하여 성능상의 이슈 없이 처리할 수 있다.
fastapi에서 세션처리하는 코드에 yield 키워드를 썼는데 그 이유도 세션은 계속 유지되어야 하는 부분이라 성능상의 문제를 일으키지 않기위한 것이었다.

profile
해삐한 다영의 컴퓨터와 친해지기 프로젝트 🥰

0개의 댓글