TIL(8) - Generator
Generator 탐구하기
대량의 값을 다루어야 할 때 유용한 Generator를 학습해보자.
- Generator의 정의: 주어진 함수의 반환값을 하나씩 그때 그때 필요시마다 발생시키는 역할을 한다.
- 특징1. 메모리 휘발성: generator는 값을 넘겨주고(소비하고) 그 해당값을 메모리에서 지운다. 즉, 이전값에 대한 정보가 사라지게 된다.
=> 따라서, 대규모 리스트를 만들어서 메모리를 잡아먹는 것이 불필요 할때, 메모리 효율 측면에서 높은 성능이 필요시 될 때 사용하면 용이하다.
=> 예시: 1에서 100000까지의 숫자 리스트를 만드는데 두가지 방법 사용 가능: (1) for loop 제너레이터를 만들어서 예를 들어 1~4까지 만들게 하고 같은 행동을 반복하게 하는 제너레이터를 발동시켜서 픽업을 하거나, (2) 1~100000까지 엄청 큰 리스트를 만드는 for loop을 실행해서 메모리상 하나하나 픽업 하는 것임.
- 특징2. 특정 계산이 필요할 때까지 대기하는 성질: 제너레이터는 기본적으로 yield 키워드의 기능을 수행하며 이는 iterating 될 때 for 문처럼 전체값을 한 번에 반환하는게 아니라; 값 하나를 반환하고 대기상태에 머물며 다음 명령을 기다리는 특징을 지닌다. 따라서 수행 시간이 긴 연산을 필요한 순간까지 늦출 수 있다는 점이 특징이 있다.
*Yield와 return의 차이점: yield는 return과 동일한 기능을 수행하는데, 단 한가지 차이점이 있다면 return 처럼 하나의 값을 반환하는 것이 아니라 제네레이터 객체를 반환한다.
<제너레이터 실습을 위한 피보나치 수열 코드>
def gen_fibon(n):
a = 1
b = 1
for i in range(n):
yield a
a, b = b, a+b
for number in gen_fibon(10):
print(number)
-
위 코드의 출력값:
1
2
3
5
8
13
21
34
55 -
위 예제 코드를 gen_fibon 함수 단독으로만 실행하면 그저 자신의 객체만을 반환하게된다. 함수 내부의 해당 코드는 추후 실제로 for 루프로 제너레이터를 돌릴 때 실행된다.
-
함수로부터 만들어진 제너레이터 객체가 for 루프를 통해 처음 실행될 때, Python은 함수 내에 있는 코드를 yield 키워드를 만나기 전까지 실행하고 첫 번째 루프의 값을 반환한다. 다음 루프 때에는 yield 키워드 뒤에 있는 코드를 실행하고 다시 루프를 돌면서 반환할 값이 모두 소진되어 없을때까지 계속 같은 과정을 반복하게 된다.
-
모든 값에 대한 반환이 완료되면 iteration이 종료된다. 모든 값은 단 한번만 순회한다는 특징을 지닌다.
<Yield의 대기하는 성질을 보여주는 코드>
#1번 예제
def simple_gen():
for x in range(3):
yield x
for number in simple_gen():
print(number)
g = simple_gen()
print(next(g)) #출력값: 0
print(next(g)) #출력값: 1
print(next(g)) #출력값: 2 이후 프로그램 종료
- 변수 g를 통해서 simple_gen() 함수를 실행하면 출력값은 for문의 루핑을 통해 0, 1, 2가 나오게 된다.
- 이 때, for문이 아닌 next(g) 메소드를 의도적으로 넣어 봄으로써; 한 번에 모든 값이 반환되지 않고 0, 1, 2에 대한 순차적인 출력 명령이 있어야지만 다음 출력 명령으로 넘어가는 Generator + Yield의 (대기하는) 특징을 확인 할 수 있다.
# 2번 예제
s = 'hello'
# for letter in s:
# print(letter)
s_iter = iter(s)
print(next(s_iter)) #h
print(next(s_iter)) #e
print(next(s_iter)) #l
print(next(s_iter)) #l
print(next(s_iter)) #o
- next(s) 위에 int타입에서 통하던 이터레이션이 여기 str타입에선 적용이 안됨. 따라서 str타입에서 이터레이션을 쓰려면 특별히 이터레이션을 첨가해주는 iter(s) 메소드를 사용해야함.
- next() 메소드의 영향으로 위 1번 예제의 출력값처럼 2번 예제도 문자열 출력값이 h, e, l, l, o하나씩 반환되는 결과를 보인다.
Author And Source
이 문제에 관하여(TIL(8) - Generator), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@kyeongraekim/Python-TIL-210331저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)