yield vs return
>>> def abc():
... data = "abc"
... for char in data:
... return char
>>> it = iter(abc()) # iter 함수를 사용해 함수 abc() 의 이터레이터 객체를 가지고 온다.
>>> next(it)
'a'
>>> next(it)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
-
처음 next(it)를 호출하면 ‘a’가 호출되지만
두 번째 호출에선 abc 함수가 끝나 버렸기 때문에 예외가 발생한다.
>>> def abc():
... data = "abc"
... for char in data:
... yield char
>>> abc
<function abc at 0x104861c80>
>>> abc() # 제너레이터가 반환됨
<generator object abc at 0x1038711a8>
>>> it = iter(abc())
>>> next(it)
'a'
>>> next(it)
'b'
>>> next(it)
'c'
-
abc()
가 실행되면제너레이터 객체
가 반환된다. -
함수의 상태
가 그대로보존
되기 때문에for문의 순회 인덱스가 초기화되지 않아 a,b,c를 순서대로 반환할 수 있다.
-
함수의 상태를 그대로 보존하고
다시 호출될 수 있다는 것 때문에 이터레이터 객체를 만들 때 매우 강력한 도구가 될 수 있다.
-
제너레이터
는메모리가 절약
된다는 장점이 있다. -
필요할 때마다 데이터를 생성할 수 있어서 메모리 사용을 줄일 수 있다.
>>> a = [1,2,3,4,5,6,7,8,9,10] # 10개의 객체를 저장할 메모리 공간이 필요하다.
>>> sum(a)
55
>>> b = (i for i in range(11))
>>> b
<generator object <genexpr> at 0x101f0df10>
>>> sum(b) # 아이템이 바로 생성되기 때문에 저장할 메모리 공간이 필요하지 않다.
55