아는 만큼 보인다

Generator란? 본문

Python

Generator란?

계토 2023. 11. 30. 21:15

# TODO: 예시 추가, iterator 추가

 

1. 개념

- Iterator를 쉽게 만들 수 있게 해주는 개념/클래스이다.

    - Iterator란 무엇인가? iteration을 통해 값을 하나씩 반환하게 해주는 object (좀 더 공부해서 추가 예정!)

- 기본적으로 iterator를 만들 수 있게 해주는 것으로, generator는 iterator이기도 하다. 그리고 iterator의 장점을 공유한다.

- iterable한 순서가 지정되면 느슨하게 평가(lazy evaluation)되어, 필요에 따라 순서의 다음 값이 계산되는 방식으로 작동한다.

- 이에 무한한 순서가 있는 객체를 메모리의 부담 없이 모델링할 수 있게 된다.

- 즉, 필요한 값들을 모두 메모리에 들고 있는 게 아니라 필요할 때 꺼내쓸 수 있게 한다. 

 

 

2. 생성 방법 2가지

    1) yield 사용

def integer_generator_ascending(n):
	value = 0
    while value < n:
    	yield value
    value += 1

 

기존 함수의 return의 경우 반환 즉시 함수가 끝나지만, yield는 함수를 끝내지 않은 상태에서 지금까지 실행중이던 값을 바깥으로 전달하여, 잠시 함수 바깥의 코드가 실행되도록 양보한다는 의미를 갖고 있다. 해당 상태에서 멈춰있는 상태이므로, 다시 호출이 되면 코드를 계속해서 실행할 수 있다.

 

for loop을 이용해 value들을 순차적으로 꺼낼 수도 있고, next()를 이용해 한번에 하나의 값을 얻을 수도 있다. 

 

iterator와 마찬가지로, 값을 내보낸 뒤에도 내부 상태가 유지되고(마지막 실행 위치를 기억하고 있음), 함수가 끝까지 도달하면 StopIteration 예외가 발생한다. 이 때 return에 반환값을 지정하면 원하는 에러메시지가 나올 수 있도록 할 수 있다.

 

iterator와 다른 점은, 클래스가 아닌 yield라는 키워드를 포함하는 '함수'로 정의된다는 점이다. iterator에 비해 비교적 단순하게/추상화하여 구현할 수 있다.

 

    2) generator comprehension/expression

g = (i for i in range(n))

 

list comprehension 처럼 ()를 사용해서 comprehension을 만들 수 있다. (tuple이 생성되지 않는다!)

yield로 구현한 것과 같은 결과를 내지만 훨씬 단순하다. 그러나 물론 list의 경우와 마찬가지로, 로직이 복잡한 경우에는 1) yield 방법을 쓰는 것이 좋다. 

 

3. 쓰임새 예시

100개 중에 2개를 뽑는 모든 가능한 조합을 구해서, 어떤 연산을 한다고 해보자. 먼저 조합을 모두 계산해서 내려놓고 연산을 하면 메모리에 부담이 갈 수 밖에 없다. 이런 경우, 조합을 만드는 규칙을 구현해서 generator (혹은 iterator)로 동작할 수 있게 하면, 메모리 부담 없이 값을 효율적으로 생성해낼 수 있다.

 

 

generator를 제대로 이해하려면 iterator에 대한 공부도 필요해서, 좀 더 공부해서 채워넣으려 한다.

 

 

출처

- https://shoark7.github.io/programming/python/iterable-iterator-generator-in-python#4

 

[Python] Iterable, Iterator 그리고 Generator

Python의 Iterable, Iterator, Generator가 궁금하십니까? 의심하지 말고 들어오세요.

shoark7.github.io

- https://docs.python.org/3/