제너레이터 사용하기
- 제너레이터
- 발생자
- 이터레이터는 클래스에 iter, next 또는 getitem 메서드를 구현해야 하지만 제너레이터는 함수 안에서 yield라는 키워드만 사용하면 끝입니다. 그래서 제너레이터는 이터레이터보다 훨씬 간단하게 작성
- 배열이나 리스트를 리턴하는 함수와 비슷하며, 호출을 할 수 있는 파라메터를 가지고 있고, 연속적인 값들을 만들어 낸다.→ but, yield 구문을 이용해 한 번 호출될 때마다 하나의 값만을 리턴해서 적은 메모리를 필요로 한다
- 제너레이터 사용이유
- 데이터셋이 클 때 메모리 문제 때문에 제너레이터 사용
- 제너레이터 객체가 이터레이터인지 확인
- yield를 사용해서 제너레이터를 만들고 for 반복문에서 0, 1, 2 숫자 세 개를 출력
>>> def number_generator():
>>> yield 0
>>> yield 1
>>> yield 2
>>>for i in number_generator():
>>> print(i)
0
1
2
>>> g = number_generator()
>>> g
<generator object number_generator at 0x03A190F0>
>>> dir(g)
['__class__', '__del__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__name__', '__ne__', '__new__', '__next__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'gi_code', 'gi_frame', 'gi_running', 'gi_yieldfrom', 'send', 'throw']
- yield의 동작 과정
- yield가 호출된다고 해서 함수가 종료되는 것이 아니다
- yield호출→함수 잠시 정지→next가 호출되면 정지된 시점부터 다시 로직 실행
- return은 호출되면 바로 함수 종료
>>> def number_generator():
>>> yield 0
>>> yield 1
>>> yield 2
>>>g = number_generator()
>>>a = next(g)
>>>print(a)
>>>b = next(g)
>>>print(b)
>>>c = next(g)
>>>print(c)
0
1
2
>>> def upper_generator(x):
>>> for i in x:
>>> yield i.upper()
>>> fruits = ['apple', 'pear', 'grape', 'pineapple', 'orange']
>>> f=upper_generator(fruits)
>>> print(next(f))
>>> print(next(f))
>>> print(next(f))
>>> print(next(f))
>>> print(next(f))
>>> print(next(f))
APPLE
PEAR
GRAPE
PINEAPPLE
ORANGE
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
/tmp/ipykernel_13/3198256348.py in <module>
10 print(next(f))
11 print(next(f))
---> 12 print(next(f))
StopIteration:
>>> def upper_generator(x):
>>> for i in x:
>>> yield i.upper()
>>> fruits = ['apple', 'pear', 'grape', 'pineapple', 'orange']
>>> for i in upper_generator(fruits):
>>> print(i)
APPLE
PEAR
GRAPE
PINEAPPLE
ORANGE
>>> my_nums = (x*x for x in [1, 2, 3, 4, 5])
>>> print(my_nums)
>>> for num in my_nums:
>>> print(num)
<generator object <genexpr> at 0x7f07ec2fa0b0>
1
4
9
16
25
*list 표현식
>>> my_nums = [x*x for x in [1, 2, 3, 4, 5]]
>>> print(my_nums)
>>> for num in my_nums:
>>> print(num)
[1, 4, 9, 16, 25]
1
4
9
16
25
>>> def upper_generator(x):
>>> yield from fruits
>>> fruits = ['apple', 'pear', 'grape', 'pineapple', 'orange']
>>> f=upper_generator(fruits)
>>> print(next(f))
>>> print(next(f))
>>> print(next(f))
>>> print(next(f))
>>> print(next(f))
APPLE
PEAR
GRAPE
PINEAPPLE
ORANGE