🐍 μ œλ„€λ ˆμ΄ν„°

νŒ”λ¦¬λ™Β·2021λ…„ 8μ›” 5일
0
post-thumbnail

파이썬 μ œλ„€λ ˆμ΄ν„°μ— λŒ€ν•΄μ„œ μ•Œμ•„λ³΄μž

μ œλ„€λ ˆμ΄ν„°

μ œλ„€λ ˆμ΄ν„°μ˜ μ •μ˜

  • iteratorλ₯Ό μƒμ„±ν•΄μ£ΌλŠ” ν•¨μˆ˜, ν•¨μˆ˜μ•ˆμ— yield ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•œλ‹€.

yieldκ°€ 뭐야!

  • ν•¨μˆ˜ μ•ˆμ—μ„œ yieldλ₯Ό μ‚¬μš©ν•˜λ©΄ ν•¨μˆ˜λŠ” μ œλ„ˆλ ˆμ΄ν„°κ°€ 되며 yieldμ—λŠ” κ°’(λ³€μˆ˜)을 μ§€μ •ν•œλ‹€.

  • generator ν•¨μˆ˜κ°€ μ‹€ν–‰ 쀑 yield λ₯Ό λ§Œλ‚  경우, ν•΄λ‹Ή ν•¨μˆ˜λŠ” κ·Έ μƒνƒœλ‘œ 정지 되며, λ°˜ν™˜ 값을 next() λ₯Ό ν˜ΈμΆœν•œ μͺ½μœΌλ‘œ 전달 ν•˜κ²Œ λœλ‹€. 이후 ν•΄λ‹Ή ν•¨μˆ˜λŠ” 일반적인 경우 처럼 μ’…λ£Œλ˜λŠ” 것이 μ•„λ‹ˆλΌ κ·Έ μƒνƒœλ‘œ μœ μ§€λ˜κ²Œ λœλ‹€.
    좜처

yield값을 λ°›λŠ” μ˜ˆμ‹œ

def generator_send():
    received_value = 0

    while True:

        received_value = yield
        print("received_value = ",end=""), print(received_value)
        yield received_value * 2

μ„€λͺ…: yield값을 λ°›μœΌλ©΄ 좜λ ₯ν•˜κ³  받은 값에 μ œκ³±μ„ ν•΄μ„œ λ°˜ν™˜ν•œλ‹€.

gen = generator_send()
next(gen)

gen에 generator_send()ν•¨μˆ˜λ₯Ό λ‹΄μ•„μ„œ next()ν•¨μˆ˜μ— 인자λ₯Ό μ€€λ‹€.
μ΄λ ‡κ²Œ 되면 received_valueμ—μ„œ 값을 λ°›κΈ°μ „κΉŒμ§€ λ©ˆμΆ°μžˆλ‹€.

print(gen.send(2))	

>>>received_value = 2
4

값을 μ£Όλ©΄ received_valueλ₯Ό 좜λ ₯ν•˜κ³  received_value에 μ œκ³±μ„ ν•œ 값을 λ°˜ν™˜ν•œλ‹€. 그리고 λ‹€μ‹œ yield값을 λ°›κΈ°μ „κΉŒμ§€ μ‹€ν–‰ν•˜κ³  κΈ°λ‹€λ¦°λ‹€.

next(gen)
print(gen.send(3))

>>>received_value = 3
6

λ˜‘κ°™μ΄ 반볡 ν•œλ‹€.

ν•˜μ§€λ§Œ!

next(gen)
next(gen)

>>>TypeError: unsupported operand type(s) for *: 'NoneType' and 'int'

next()ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜κ³  값을 μ•ˆμ£Όκ³  또 next()λ₯Ό ν˜ΈμΆœν•˜λ©΄ λ°˜ν™˜κ°’μ΄ μ—†μ–΄μ„œ 였λ₯˜κ°€ λ‚œλ‹€.

즉 yieldλŠ” ν•¨μˆ˜μ˜ 흐름을 μ œμ–΄ν•  수 μžˆλ‹€.

Lazy Evaluation

μ •μ˜

컴퓨터 ν”„λ‘œκ·Έλž˜λ°μ—μ„œ λŠκΈ‹ν•œ 계산법(Lazy evaluation)은 κ³„μ‚°μ˜ 결과값이 ν•„μš”ν•  λ•ŒκΉŒμ§€ 계산을 λŠ¦μΆ”λŠ” 기법이닀. 두 가지 κ΄€λ ¨λœ ν•­λͺ©λ“€μ΄ μžˆλŠ”λ° 지연 계산법과 μ΅œμ†Œ 계산법이닀.

λŠκΈ‹ν•˜κ²Œ κ³„μ‚°ν•˜λ©΄ ν•„μš”μ—†λŠ” 계산을 ν•˜μ§€ μ•ŠμœΌλ―€λ‘œ 싀행을 더 λΉ λ₯΄κ²Œ ν•  수 있고, 볡합 μˆ˜μ‹μ„ 계산할 λ•Œ 였λ₯˜ μƒνƒœλ₯Ό ν”Όν•  수 있고, λ¬΄ν•œ 자료 ꡬ쑰λ₯Ό μ“Έ 수 있고, 미리 μ •μ˜λœ 것을 μ΄μš©ν•˜μ§€ μ•Šκ³  보톡 ν•¨μˆ˜λ‘œ μ œμ–΄ ꡬ쑰λ₯Ό μ •μ˜ν•  수 μžˆλ‹€.
좜처

μœ„μ—λŠ” μœ„ν‚€λ°±κ³Όμ—μ„œ λ‚΄λ¦° μ •μ˜μ΄κ³ 
lazy evaluation을 μ΄ν•΄ν•˜κΈ° μœ„ν•΄μ„œ 리슀트 ν‘œν˜„μ‹κ³Ό μ œλ„€λ ˆμ΄ν„° ν‘œν˜„μ‹κ³Ό λΉ„κ΅ν•˜λ©΄μ„œ μ•Œμ•„λ³΄μž

μ œλ„ˆλ ˆμ΄ν„° ν‘œν˜„μ‹(generator expression)

  • μ œλ„ˆλ ˆμ΄ν„° ν‘œν˜„μ‹μ€ Lazy evaluation을 μœ„ν•΄μ„œ μ‚¬μš©λ  수 μžˆλ‹€.
  • λ¦¬μŠ€νŠΈν‘œν˜„μ‹κ³Ό 같이 λ§Œλ“œλŠ”λ° [] λŒ€μ‹  ()λ₯Ό μ‚¬μš©ν•œλ‹€.

μ œλ„€λ ˆμ΄ν„° ν‘œν˜„μ‹μ„ 잘 μ‚¬μš©ν•œ μ˜ˆμ‹œλ₯Ό 보자

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("comprehension_list_print")
print_iter(comprehension_list)

print("generator_exp=")
generator_exp = ( lazy_return(i) for i in L )
print("generators_exp_print")
print_iter(generator_exp)

comprehension_listλŠ” 리슀트 ν‘œν˜„μ‹μœΌλ‘œ lazy return을 μƒμ„±ν•˜κ³ 
generator_expλŠ” μ œλ„€λ ˆμ΄ν„° ν‘œν˜„μ‹μœΌλ‘œ lazy return을 μƒμ„±ν•œλ‹€.

κ·Έλ ‡κ²Œ μƒμ„±λœ μ΄ν„°λ ˆμ΄λΈ” κ°μ²΄μš”μ†Œν•˜λ‚˜μ”© 좜λ ₯ν•˜λŠ”print_iter()ν•¨μˆ˜μ— 집어 λ„£λŠ”λ‹€.

자 이제 μ‹€ν–‰ν•΄ 보자!

comprehension_list=
sleep 1s
sleep 1s
sleep 1s
comprehension_list_print
1
2
3
generator_exp=
generators_exp_print
sleep 1s
1
sleep 1s
2
sleep 1s
3

μ†Œλ¦„μ΄ λ‹λŠ”λ‹€!!

리슀트 ν‘œν˜„μ‹μœΌλ‘œ μ‹€ν–‰ν•˜λ©΄

comprehension_list=
sleep 1s
sleep 1s
sleep 1s
comprehension_list_print
1
2
3

μ΄λ ‡κ²Œ λ¦¬μŠ€νŠΈμ— μš”μ†Œλ₯Ό μ „λΆ€ μƒμ„±ν•΄μ„œ 집어 λ„£μ—ˆλ‹€λŠ”κ±Έ μ•Œ 수 μžˆλ‹€.
반면 μ œλ„€λ ˆμ΄ν„° ν‘œν˜„μ‹μ„ 보면

generator_exp=
generators_exp_print
sleep 1s
1
sleep 1s
2
sleep 1s
3

generator_exp=밑에 아무것도 μ—†λŠ”κ±Έ λ³΄λ‹ˆ μ•„μ˜ˆ ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•˜μ§€λ„ μ•Šμ•˜λ‹€.
generators_exp_printλŠ” print_iterν•¨μˆ˜κ°€ μ‹€ν–‰λ˜κ³  λ‚˜μ„œ λ‚˜μ˜€λŠ” κ²ƒμ΄λ―€λ‘œ μ œλ„€λ ˆμ΄ν„° ν‘œν˜„μ‹μœΌλ‘œ ν•œ 녀석은 μš”μ†Œλ₯Ό μ“°κΈ°μ „κΉŒμ§€λŠ” ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•˜μ§€ μ•Šμ•˜λ‹€.

Lazy Evaluation의 μž₯점

  • μœ„ μ˜ˆμ œμ™€ μž‘λ™λ°©μ‹μ—μ„œ λ³΄μ•˜λ“―μ΄ Lazy Evaluation은 ν•„μš”ν•  λ•Œ κ°€μ•„λ‹ˆλ©΄ λ©”λͺ¨λ¦¬μ— 적재λ₯Ό ν•˜μ§€ μ•ŠλŠ”λ‹€. κ·ΈλŸ¬λ―€λ‘œ λ©”λͺ¨λ¦¬ λ‚­λΉ„λ₯Ό(λ¦¬μ†ŒμŠ€ λ‚­λΉ„)λ₯Ό 방지할 수 μžˆλ‹€.
profile
λ°°μ›€μ˜ 기둝

0개의 λŒ“κΈ€