TIL-079 | Python_ Generator

Lee, Chankyuยท2022๋…„ 2์›” 2์ผ
0
post-thumbnail

๐ŸŒˆ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ (Generator)

์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋ž€?

  • ์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋Š” iterator๋ฅผ ์ƒ์„ฑํ•ด์ฃผ๋Š” ํ•จ์ˆ˜์ด๋‹ค.
  • ์ผ๋ฐ˜์ ์ธ ํ•จ์ˆ˜๋Š” return ํ‚ค์›Œ๋“œ๋ฅผ ํ†ตํ•ด ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜์ง€๋งŒ, ์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋Š” yield ํ‚ค์›Œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ๊ฒฐ๊ณผ ๊ฐ’์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. ์•„๋ž˜์˜ ์˜ˆ์‹œ๋ฅผ ๋ณด๋„๋ก ํ•˜์ž.
def generator(n):
    i = 0
    while i < n:
        yield i
        i += 1
  • ํ•จ์ˆ˜์˜ ์‹คํ–‰์ค‘ yield๋ฅผ ๋งŒ๋‚˜๊ฒŒ ๋  ๊ฒฝ์šฐ, ํ•ด๋‹น ํ•จ์ˆ˜๋Š” ๊ทธ ์ƒํƒœ๋กœ ์ •์ง€ ๋˜๋ฉฐ, ๋ฐ˜ํ™˜ ๊ฐ’์„ next() ๋ฅผ ํ˜ธ์ถœํ•œ ์ชฝ์œผ๋กœ ์ „๋‹ฌ ํ•˜๊ฒŒ ๋œ๋‹ค. ์ดํ›„ ํ•ด๋‹น ํ•จ์ˆ˜๋Š” ์ผ๋ฐ˜์ ์ธ ๊ฒฝ์šฐ ์ฒ˜๋Ÿผ ์ข…๋ฃŒ๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๊ทธ ์ƒํƒœ๋กœ ์œ ์ง€๋˜๊ฒŒ ๋œ๋‹ค. ์ฆ‰, ํ•จ์ˆ˜์—์„œ ์‚ฌ์šฉ๋œ local ๋ณ€์ˆ˜๋‚˜ instruction pointer ๋“ฑ๊ณผ ๊ฐ™์€ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉ๋œ ๋ฐ์ดํ„ฐ๋“ค์ด ๋ฉ”๋ชจ๋ฆฌ์— ๊ทธ๋Œ€๋กœ ์œ ์ง€๋œ๋‹ค.

์ด๋ฏธ์ง€ ์ถœ์ฒ˜


generator expression

  • list comprehension๊ณผ ์œ ์‚ฌํ•œ ๋ฐฉ์‹์œผ๋กœ generator expression์„ ์ œ๊ณตํ•œ๋‹ค. list comprehension์˜ [] ๋Œ€์‹  ()๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.
a = [i for i in range(5)]
print(a) # [0, 1, 2, 3, 4]

b = (i for i in range(5))
print(b) # <generator object <genexpr> at 0x7f1235d1ff90>
  • ์œ„์˜ ์˜ˆ์‹œ์™€ ๊ฐ™์ด generator object๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค.

์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ?

โœ” memory๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

import sys

#list
sys.getsizeof( [i for i in range(100) if i % 2] )    
# 520

sys.getsizeof( [i for i in range(500) if i % 2] )
# 2208

#generator
sys.getsizeof( (i for i in range(100) if i % 2) )    
# 112

sys.getsizeof( (i for i in range(500) if i % 2) )
# 112
  • ๋ฆฌ์ŠคํŠธ์˜ ๊ฒฝ์šฐ ์‚ฌ์ด์ฆˆ๊ฐ€ ์ปค์งˆ ์ˆ˜๋ก ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ด ๋Š˜์–ด๋‚œ๋‹ค. ํ•˜์ง€๋งŒ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋Š” ์‚ฌ์ด์ฆˆ๊ฐ€ ์ปค์ ธ๋„ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉํ–ฅ์€ ๋™์ผํ•˜๋‹ค.
  • ๋ฆฌ์ŠคํŠธ๋Š” ๋ฆฌ์ŠคํŠธ์— ์†ํ•œ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์— ์ ์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฆฌ์ŠคํŠธ์˜ ํฌ๊ธฐ๋งŒํผ ๋ฉ”๋ชจ๋ฆฌ์˜ ์‚ฌ์ด์ฆˆ๊ฐ€ ๋Š˜์–ด๋‚˜๋Š” ๊ฒƒ์ด๊ณ , ์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋Š” next() ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด ์ฐจ๋ก€๋กœ ๊ฐ’์— ์ ‘๊ทผํ•  ๋•Œ๋งˆ๋‹ค ๋ฉ”๋ชจ๋ฆฌ์— ์ ์žฌํ•œ๋‹ค.
  • ๋ฆฌ์ŠคํŠธ์˜ ๊ทœ๋ชจ๊ฐ€ ํด์ˆ˜๋ก ์ œ๋„ˆ๋ ˆ์ดํ„ฐ์˜ ํšจ์œจ์„ฑ์ด ์ฆ๊ฐ€ํ•œ๋‹ค.

โœ” Lazy evaluation ์ฆ‰ ๊ณ„์‚ฐ ๊ฒฐ๊ณผ ๊ฐ’์ด ํ•„์š”ํ•  ๋•Œ๊นŒ์ง€ ๊ณ„์‚ฐ์„ ๋Šฆ์ถ”๋Š” ํšจ๊ณผ

def sleep_func(x):
    print ("sleep")
    time.sleep(1)
    return x

# list ์ƒ์„ฑ
list = [sleep_func(x) for x in xrange(5)]

for i in list:
    print i
    
#๊ฒฐ๊ณผ ๊ฐ’
sleep
sleep
sleep
sleep
sleep
0
1
2
3
4

# generator ์ƒ์„ฑ
gen = (sleep_func(x) for x in xrange(5))

for i in gen:
    print i
    
#๊ฒฐ๊ณผ ๊ฐ’
sleep
0
sleep
1
sleep
2
sleep
3
sleep
4
  • list comprehension ์„ ์ˆ˜ํ–‰ ํ• ๋•Œ, list์˜ ๋ชจ๋“  ๊ฐ’์„ ๋จผ์ € ์ˆ˜ํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์— sleep_func() ํ•จ์ˆ˜๋ฅผ xrange() ๊ฐ’ ๋งŒํผ ํ•œ๋ฒˆ์— ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋œ๋‹ค. ๋งŒ์•ฝ sleep_func() ์—์„œ ์ˆ˜ํ–‰ํ•˜๋Š” ์‹œ๊ฐ„์ด ๊ธธ๊ฑฐ๋‚˜ list ๊ฐ’์ด ๋งค์šฐ ํฐ ๊ฒฝ์šฐ ์ฒ˜์Œ ์ˆ˜ํ–‰ ํ• ๋•Œ ๊ทธ๋งŒํผ ๋ถ€๋‹ด์œผ๋กœ ์ž‘์šฉ๋œ๋‹ค.

  • generator ์˜ ๊ฒฝ์šฐ generator๋ฅผ ์ƒ์„ฑํ•  ๋•Œ๋Š” ์‹ค์ œ ๊ฐ’์„ ๋กœ๋”ฉํ•˜์ง€ ์•Š๊ณ , for ๋ฌธ์ด ์ˆ˜ํ–‰ ๋ ๋•Œ ํ•˜๋‚˜์”ฉ sleep_func()์„ ์ˆ˜ํ–‰ํ•˜๋ฉฐ ๊ฐ’์„ ๋ถˆ๋Ÿฌ์˜ค๊ฒŒ ๋œ๋‹ค. ์ˆ˜ํ–‰ ์‹œ๊ฐ„์ด ๊ธด ์—ฐ์‚ฐ์„ ํ•„์š”ํ•œ ์ˆœ๊ฐ„๊นŒ์ง€ ๋Šฆ์ถœ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด ํŠน์ง•์ด๋‹ค.


๐Ÿ“ Reference

  1. https://bluese05.tistory.com/56
  2. https://www.daleseo.com/python-yield/
  3. https://ssungkang.tistory.com/entry/python%EC%A0%9C%EB%84%88%EB%A0%88%EC%9D%B4%ED%84%B0generator%EB%A5%BC-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90
profile
Backend Developer - "Growth itself contains the germ of happiness"

0๊ฐœ์˜ ๋Œ“๊ธ€

๊ด€๋ จ ์ฑ„์šฉ ์ •๋ณด