brunch

Generator 함수

#파이썬, #제너레이터, #이터러블

by 유윤식

Python

... Generator

...Iter


둘다 알아야함.


언제 Generator 를 쓰는지.

메모리가 뻑날 때,

예를 들어 메모리에 한 번에 10G 데이터를 올리면,

실제로는 메모리는 10G 보다 더 많은 공간을 필요로하고,

보통은 뻑남.


그 외에도 이유가 있지만,

난 Deep Learning 에서 데이터를 생성하는 로직을

보통 Generator 방식으로 활용하기 때문에,

그냥 아무데서나 Generator 를 사용.


쉬운 예제.

이중루프를 돌면서 원하느 값을 가진 위치(예로 Matrix 에서 row, col 의 위치) 찾기!


function 1


def double_loop(arr):

for row_loc, row_value in enumerate(arr):

for col_loc, col_value in enumerate(row_value):

yield (row_loc, col_loc), col_value


function 2


def find_value(arr, target):

res = []

iter_obj = double_loop(arr) # Check this part!

for i, j in iter_obj:

if j == target:

res.append((i, j))

return res


execute 1


%%time

result = find_value([ list(range(1, 5000)), list(range(1000)), list(range(10, 4000)) ], 20)


yield 를 통해서 return을 주는 함수 자체가 제너레이터.

또한 for 구문에서 작동함으로,

iterable 하다.


굳이 next 를 불러서 어쪄구 저쪄구...

과정은 생략.


근데 중요한게,


class IterTest:

def __init__(self, start=0, step=1):

self.current = start

self.step = step

def __next__(self):

value = self.current

self.current += self.step

return value

def __iter__(self):

return self


정말 간단하지만, 꼭 알면 좋은게...


아무데서나 제너레이터를 막 쓰는 케이스가 종종 있는데,

이렇게 만들어서 사용한다.



test = IterTest(0, 2)


이렇게 하면 test 변수는 Generator Function 이 되고(자바스크립트랑 거의 유사)

test 자체가 Iterable 하다.


위에서 __next__ 매직함수만 정의하면,

for 문에서 사용이 안된다.


간단히 테스트해보면,


for i, j in enumerate(test):

print(i, j)

if i == 3:

break


결과는 뭐... 머릿속으로 생각하는 그것이 맞다.


개념을 깊게 가져가보니,

코루틴과 깊은 연관(?) 까지는 모르겠지만 어느정도 Coupling 되어 있는 듯 보인다.


코루틴까지 확인해보고,

Generator 를 확장시켜서 사용해보면 좋을 듯.


** Tensorflow 데이터 관련 함수는 모두 위와 같은 형태로 만들어진다.

keyword
작가의 이전글Anonymous 함수