TIL #27에 iterator에 대한 글을 올렸다. 이런 iterator을 만들어 사용 할 수 있게 해주는 것을 generator 라고 한다.
def generator_squares():
for i in range(3):
yield i ** 2
gen = generator_squares()
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))
> 출력 결과
0
1
4
Traceback (most recent call last):
File "/Users/apple/Documents/Python/run.py", line 86, in <module>
print(next(gen))
StopIteration
- 함수 내에 yield을 사용했으므로 generator function
- 처음 geneator_squares()을 호출 할 때는 함수 실행 X
- next을 통해서 함수를 실행하고, yield을 통해서 정지
- next를 계속 하다가 마지막 iternation이 끝나게 되면 StopIternation 예외 발생
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)) # yield에 2를 전송 후 결과 출력
next(gen)
print(gen.send(3)) # yield에 3을 전송 후 결과 출력
> 출력 결과
received_value = 2
4
received_value = 3
6
- gen에 generator_send() 저장
- next을 통해 함수를 실행 후, receuved_value = yield에서 yield을 만나 함수 정지
- .send()을 통해 yield에 값을 보내고 함수 재실행
def generate_square_from_list():
result = ( x*x for x in L ) # generator expression
print(result)
return result #iterator을 return
def print_iter(iter):
for element in iter:
print(element)
print_iter(generate_square_from_list())
#ptint_iter는 매개변수로 iterator을 받음
- result = (x*x for x in L) 을 보면 list conprehension과 모양이 비슷
- result는 list가 아닌 iterator
- result = iter([x*x for x in L]) 과 같은 효과
def print_iter(iter):
for element in iter:
print(element)
def lazy_return(num):
print("sleep 1s")
time.sleep(1)
return num
L = [ 1,2,3]
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)
> 출력 결과
comprehension_list=
sleep 1s
sleep 1s
sleep 1s
1
2
3
generator_exp=
sleep 1s
1
sleep 1s
2
sleep 1s
3