#파이썬, #제너레이터, #이터러블
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 데이터 관련 함수는 모두 위와 같은 형태로 만들어진다.