๐Ÿ ์ œ๋„ค๋ ˆ์ดํ„ฐ

ํŒŒ์ด์ฌ ์ œ๋„ค๋ ˆ์ดํ„ฐ์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์ž

์ œ๋„ค๋ ˆ์ดํ„ฐ

์ œ๋„ค๋ ˆ์ดํ„ฐ์˜ ์ •์˜

  • 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์€ ํ•„์š”ํ•  ๋•Œ ๊ฐ€์•„๋‹ˆ๋ฉด ๋ฉ”๋ชจ๋ฆฌ์— ์ ์žฌ๋ฅผ ํ•˜์ง€ ์•Š๋Š”๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ ๋ฉ”๋ชจ๋ฆฌ ๋‚ญ๋น„๋ฅผ(๋ฆฌ์†Œ์Šค ๋‚ญ๋น„)๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ข‹์€ ์›นํŽ˜์ด์ง€ ์ฆ๊ฒจ์ฐพ๊ธฐ