Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

Python yield 키워드 완벽 가이드: 제너레이터의 핵심 이해하기

Python yield 키워드 사용 방법

제너레이터(generator)는 파이썬에서 다소 생소하게 느껴질 수 있는 개념입니다. 더욱 혼란스러운 점은, 제너레이터 자체가 함수인데도 불구하고 'yield'라는 특별한 키워드를 사용한다는 것입니다. yield 키워드는 정확히 무엇이며, return 문과는 어떻게 다를까요?

아주 좋은 질문들입니다. 이 가이드에서는 yield 문이 무엇인지, 그리고 코드에서 어떻게 활용할 수 있는지 살펴보겠습니다. 실제 예제를 통해 yield 키워드의 동작 방식도 함께 확인해 보겠습니다. 그럼 시작해 보겠습니다!

본격적으로 시작하기 전에 파이썬 이터레이터와 제너레이터에 관한 글을 먼저 읽어보시길 권합니다. 이를 통해 yield 키워드에 대한 이해를 더욱 깊게 하는 데 도움이 되는 배경 지식을 쌓을 수 있습니다.

기본 개념 복습: 이터레이터와 제너레이터

리스트(list)는 반복 가능한(iterable) 객체로 분류됩니다. 'for' 루프를 통해 내용물을 확인할 수 있기 때문입니다. 루프가 실행될 때마다 파이썬은 리스트의 항목에 하나씩 접근합니다. 딕셔너리, 튜플, 문자열 역시 반복 가능한 객체입니다.

반복 가능한 객체에서 항목에 접근하는 함수를 이터레이터(iterator)라고 부릅니다. 리스트를 만들고 for 루프로 순회하는 예제를 살펴보겠습니다:

peppers = ["Scotch Bonnet", "Piri Piri", "Cayenne"]

for p in peppers:
	print(p)
for p in peppers:
	print(p)

이 코드는 'peppers' 리스트의 모든 고추 이름을 콘솔에 출력합니다:

Scotch Bonnet
Piri Piri
Cayenne
Scotch Bonnet
Piri Piri
Cayenne

이터레이터는 원하는 만큼 몇 번이든 사용할 수 있습니다. 위 예제에서는 'peppers' 객체를 두 번 순회했습니다.

파이썬 제너레이터는 객체를 반복하는 이터레이터와 비슷하지만, 한 가지 큰 차이점이 있습니다. 바로 제너레이터는 한 번만 순회할 수 있다는 점입니다. 'peppers' 리스트는 원하는 만큼 반복해서 접근할 수 있지만, 제너레이터는 단 한 번만 접근할 수 있습니다.

그럼 고추 리스트를 위한 제너레이터를 직접 정의해 보겠습니다:

def print_peppers(peppers):
	for p in peppers:
		yield p

peppers = ["Scotch Bonnet", "Piri Piri", "Cayenne"]
pepper_generator = print_peppers(peppers)

for p in pepper_generator:
	print(p)

print_peppers()라는 함수를 정의했습니다. 이것이 바로 제너레이터 함수입니다. 이 함수는 하나의 인자, 즉 콘솔에 출력할 고추 리스트를 받습니다.

메인 프로그램에서 print_peppers() 함수를 호출하고 그 결과를 pepper_generator 변수에 할당합니다. 그다음 'for' 루프를 사용해 제너레이터를 순회합니다. for 루프가 제너레이터 객체를 호출하며 하나씩 값을 가져오는 방식입니다.

코드를 실행해 보겠습니다:

Scotch Bonnet
Piri Piri
Cayenne

출력 결과는 첫 번째 예제와 동일합니다. 하지만 차이점이 있습니다. 제너레이터는 리스트를 한 번만 순회할 수 있습니다. 제너레이터를 다시 순회하려고 하면 어떻게 될까요?

...
for p in pepper_generator:
	print(p)
for p in pepper_generator:
	print(p)

코드 실행 결과는 다음과 같습니다:

Scotch Bonnet
Piri Piri
Cayenne

제너레이터를 이미 한 번 순회했기 때문에 두 번째 for 루프에서는 아무 값도 출력되지 않습니다. 이것이 제너레이터의 핵심 특징입니다.

Python yield 키워드란?

앞선 예제에서 'yield'라는 단어를 눈치채셨나요? 다시 한번 살펴보겠습니다:

def print_peppers(peppers):
	for p in peppers:
		yield p

'yield' 키워드는 함수 내부에 위치하며, 제너레이터 함수에서 값을 하나씩 반환하는 역할을 합니다. 'return' 키워드와 비슷하지만 결정적인 차이가 있습니다.

순회할 수 있는 제너레이터를 만들고 싶을 때 yield를 사용합니다. 앞선 예제에서는 yield를 사용해 고추 리스트의 제너레이터를 생성했습니다.

중요한 점은, yield를 포함하는 모든 함수는 자동으로 제너레이터를 반환한다는 것입니다. type() 메서드로 pepper_generator 변수의 타입을 확인해 보면 알 수 있습니다:

<class 'generator'>

print_peppers 함수가 할당된 pepper_generator가 제너레이터 클래스의 인스턴스임을 확인할 수 있습니다.

마무리

yield 키워드는 제너레이터 내부에서 값을 하나씩 반환합니다. 제너레이터는 값들을 딱 한 번만 순회할 수 있는 특별한 종류의 이터레이터입니다. yield 키워드는 return 문과 비슷하지만, return 문은 제너레이터에서 사용할 수 없다는 차이점이 있습니다.

이제 여러분도 yield 키워드를 파이써닉(Pythonic)하게 활용할 준비가 되었습니다!