Programming Language/Python

제너레이터

D4tai1 2018. 8. 10.

1. Generator

- iterator를 생성해주는 함수이다.

- 겉보기에는 일반적인 함수와 비슷해 보이지만 return 대신에 yield 라는 것이 있다는 것이 차이점이다.

 

1) 일반함수

- return문을 사용하여 결과 값을 반환하고 stack pointer 복구 후 함수를 종료한다.

 

2) yield

- 함수가 실행 중 yield를 만나면 함수는 일시정지

  +[상태 유지(지역변수 및 instruction pointer는 메모리에 유지)]

- 반환값을 next() 메소드를 호출한 쪽으로 전달

 

def generator() :
    print "start"
    for x in range(5) :
        yield x*x

for i in generator() :
    print i,  

 

[실행결과]

start
0 1 4 9 16

 

[실행순서]

[1] 6라인의 for문이 실행되면서 generator() 함수 호출

[2] "start" 출력

[3] 3라인의 for문에서 x == 0 일 때, 4라인에서 yield x*x를 만나고,

  0*0의 값을 caller에게 반환[이 때 함수는 일시정지]

[4] 6라인의 generator()의 반환 값이 i로 들어가고 7라인에서 0 출력

[5] 이 후 6라인에서 for문에 의해 generator() 함수 호출

[6] 이 때 함수의 처음부터 시작되지 않고 yield문 이후부터 진행

[7] 3라인의 for문에서 x == 1 일 때, 4라인에서 yield x*x를 만나고.

  1*1의 값을 caller에게 반환[이 때 함수는 일시정지] - 반복

[8] 6라인 for문의 generator()함수의 반환 값이 있을 때까지 반복 

 

3) Generator Comprehension

- 리스트의 컴프리핸션과 동일하지만 대괄호 [] 대신 소괄호 ()를 사용한다.

- 튜플은 컴프리핸션이 없다.

[소스]

gen_com = (x for x in range(10) if x % 2)

for i in gen_com :
    print i,
    

 

[실행결과]

1 3 5 7 9

 

4) generator를 사용하는 이유?

- 메모리의 효율적인 사용

 

[소스]

import sys

print "list_size(10) =", sys.getsizeof([x for x in range(10)])
print "list_size(100) =", sys.getsizeof([x for x in range(100)])
print "list_size(1000) =", sys.getsizeof([x for x in range(1000)])
print '------------------------------------'
print "generator_size(10) =", sys.getsizeof((x for x in range(10)))
print "generator_size(100) =", sys.getsizeof((x for x in range(100)))
print "generator_size(1000) =", sys.getsizeof((x for x in range(100)))

 

[실행결과]

list_size(10) = 192
list_size(100) = 912
list_size(1000) = 9024
------------------------------------
generator_size(10) = 72
generator_size(100) = 72
generator_size(1000) = 72

 

 

 

5) list와 generator의 메모리 사용량이 다른 이유?

- list는 사이즈가 커질수록 메모리 사용량이 증가하고, generator는 사이즈가 커져도 메모리 사용량이 일정하다.

- list는 모든 데이터를 메모리에 적재하기 때문에 list의 사이즈만큼 메모리의 사용량이 증가하게 된다.

- 반면 generator는 데이터 값을 한 번에 메모리에 적재하지 않고,

next() 메소드를 통해 순차적으로 접근 시에 메모리에 적재한다.

 

 

'Programming Language > Python' 카테고리의 다른 글

Anaconda3 설치방법  (0) 2018.09.04
제너레이터_문제  (0) 2018.08.10
이터레이터  (0) 2018.08.10
입력  (0) 2018.08.10
변환  (0) 2018.08.10

댓글