def number_generator():
yield 0 # 0을 함수 바깥으로 전달하면서 코드 실행을 함수 바깥에 양보
yield 1 # 1을 함수 바깥으로 전달하면서 코드 실행을 함수 바깥에 양보
yield 2 # 2를 함수 바깥으로 전달하면서 코드 실행을 함수 바깥에 양보
g = number_generator()
a = next(g) # yield를 사용하여 함수 바깥으로 전달한 값은 next의 반환값으로 나옴
print(a) # 0
b = next(g)
print(b) # 1
c = next(g)
print(c) # 2
number_generator() 함수는 값을 return하지 않고 yield라는 키워드를 쓴 후
g라는 Generator를 만들어 값을 순서대로 '산출'하고 있다.
직관적으로 이해하자면, 함수의 반환값을 내가 원하는 순간에 '산출'할 수 있다라고 생각하면 쉽다.
아래와 같이 내가 원할 때 함수의 결과값을 yield를 써서 순서대로 산출할 수 있다.
def generator_squares():
for i in range(3):
yield i ** 2
gen = generator_squares()
print(gen.__next__()) # 0
print(gen.__next__()) # 1
print(gen.__next__()) # 4
def generator_send():
received_value = 0
while True:
received_value = yield
print("received_value = ",end=""), print(received_value)
yield received_value * 2
gen = generator_send()
next(gen)
print(gen.send(2))
next(gen)
print(gen.send(3))
result = (x*x for x in L)
gen = result.__iter__()
print(gen.__next__()) # 1
print(gen.__next__()) # 4
print(gen.__next__()) # 9
import time
def print_iter(iter):
for element in iter:
print(element)
def lazy_return(num):
print("sleep 1s")
time.sleep(1)
return num
print("comprehension_list=")
comprehension_list = [ lazy_return(i) for i in L ]
print_iter(comprehension_list)
print("generator_exp=")
generator_exp = ( lazy_return(i) for i in L )
print_iter(generator_exp)
위의 코드를 실행해보면, List Comprehension으로 lazy_return함수를 호출했을 때는, lazy_return 함수를 3번 부른 후, print_iter함수를 호출했다.
즉, comprehension_list가 다 끝날때까지 print_iter함수를 보류한다.
그러나, generator expression을 사용한 아래 함수의 경우, iterator 객체에 변수를 호출할 때에만 lazy_return함수를 실행한다.
결론적으로, Generator Expression을 사용할 때는 함수 호출을 필요할 때만 할 수 있기 때문에, 메모리 측면에서 훨씬 효율적이라고 볼 수 있다.