본문 바로가기

Python/Intermediate

[Python] 병행성(Concurrency) - generator

Iterator, Generator - 값을 차례대로 가져올 수 있음

 

 

# Generator Ex1, yield 키워드가 있으면 제너레이터로 처리됨
def generator_ex1():
    print('start')
    yield 'A_Point'
    print('continue')
    yield 'B_Point'
    print('end')

temp = iter(generator_ex1())

print(temp)
print(next(temp))
print(next(temp))
print(next(temp)) ==> 여기서 예외처리 발생.

--------------------------------------------[result]

< generator object generator_ex1 at 0x000002B83203EEB8 >
start
A_Point
continue
B_Point
end
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
< ipython-input-54-15948090f6f3 > in < module >
     12 print(next(temp))
     13 print(next(temp))
---> 14 print(next(temp))
     15 
     16 print()

StopIteration: 
for v in generator_ex1(): # ==> for 문은 예외처리를 해줌.
    print(v)

--------------------------------------------[result]

start
A_Point
continue
B_Point
end

 

 

Comprehenstion & Generator 생성

  • Comprehenstion 리스트는 생성시 결과가 메모리에 저장되므로 리스트 생성과 동시에 print문이 동시에 출력됨
  • Generator 는 생성시 메모리 할당이 발생하지 않아서 print문이 출력되지 않음, next 호출시 출력됨

 

# Generator Ex2
temp2 = [x * 3 for x in generator_ex1()] # 여기서 start, continue, end 출력 발생
temp3 = (x * 3 for x in generator_ex1())

print('--------------------------------')
print(type(temp2))
print(type(temp3))

print('temp2: ', temp2)
print('-----------------------------------')
print('temp3 GG: ', (temp3))

print()
print('for temp2 -----------------------------------') # 다시 for문 실행 가능
for i in temp2:
    print('temp2: ', i)

print()
print()

print('for temp3 GG-----------------------------------') # 다시 for문 실행 불가, 오류발생
for i in temp3:
    print('temp3: ', i, end=' ')
    print()
# print(next(temp3)) # <== 메모리에 값이 없으므로 오류 발생(예외처리 발생)
--------------------------------------------[result]

start
continue
end
-------------------------------- print() 시작전에 리스트 생성시 start, continue, end 출력됨
< class 'list' >
< class 'generator' >
temp2:  ['A_PointA_PointA_Point', 'B_PointB_PointB_Point']
-----------------------------------
temp3 GG:  < generator object < genexpr > at 0x000002B832044200 >

for temp2 -----------------------------------
temp2:  A_PointA_PointA_Point
temp2:  B_PointB_PointB_Point


for temp3 GG-----------------------------------
start
temp3:  A_PointA_PointA_Point 
continue
temp3:  B_PointB_PointB_Point 
end

 

Generator 메모리 처리 샘플 코드

 

def square_numbers(nums):
    for i in nums:
        yield i * i
 
my_nums = square_numbers(([1,2,3,4,5]))
print(my_nums, type(my_nums))
print()

for num in my_nums: # 주석처리하면 b 로 시작하는 for 문이 출력됨.
    print('a', num)
for num in my_nums: # 메모리가 비어 있어서 출력되는게 없음.
    print('b', num)

--------------------------------------------[result]

< generator object square_numbers at 0x000002B832000CA8 > < class 'generator' >

a 1
a 4
a 9
a 16
a 25

 

itertools 관련 패키지 모음 - count, takewhile, filterfalse, accumulate, chain, product, groupby

 

import itertools

# 무한 반복문
gen1 = itertools.count(1, 2.5)
print(type(gen1))
print(gen1)
print() 

print(next(gen1))
print(next(gen1))
print(next(gen1))
print(next(gen1))
--------------------------------------------[result]
< class 'itertools.count' >
count(1, 2.5)

1
3.5
6.0
8.5

--------------------------------------------
--------------------------------------------

# 무한 반복문, 조건 추가
gen2 = itertools.takewhile(lambda n : n <= 11, itertools.count(1, 2.5))
print(type(gen2))
print(gen2)
print(next(gen2))
print()

for v in gen2:
    print(v)
--------------------------------------------[result]
< class 'itertools.takewhile' >
< itertools.takewhile object at 0x000002B831FF9E48 >
1

3.5
6.0
8.5
11.0

--------------------------------------------
--------------------------------------------

# 필터 반대, 1,2 제외하고 출력함. 'n>=3' 과 동일한 효과
gen3 = itertools.filterfalse(lambda n : n < 3, [1,2,3,4,5])

for v in gen3:
    print(v)
--------------------------------------------[result]
3
4
5

--------------------------------------------
--------------------------------------------

# 필터처리
gen3 = filter(lambda n : n < 3, [1,2,3,4,5])

for v in gen3:
    print(v)
--------------------------------------------[result]
1
2

--------------------------------------------
--------------------------------------------

# 누적 합계
gen4 = itertools.accumulate([x for x in range(1, 11)])

for v in gen4:
    print(v)
--------------------------------------------[result]
1
3
6
10
15
21
28
36
45
55

--------------------------------------------
--------------------------------------------

# 연결1
gen5 = itertools.chain('ABCDE', range(1,11,2))
print(gen5)
print(list(gen5))

# 연결2
gen6 = itertools.chain(enumerate('ABCDE'))
# 1번만 실행됨.

print(dict(gen6)) # 둘중 한곳에서만 출력됨
print(list(gen6)) # 둘중 한곳에서만 출력됨
--------------------------------------------[result]
< itertools.chain object at 0x000002B831F63C18 >
['A', 'B', 'C', 'D', 'E', 1, 3, 5, 7, 9]
{0: 'A', 1: 'B', 2: 'C', 3: 'D', 4: 'E'}
[]

--------------------------------------------
--------------------------------------------

# 개별, tuple 의 리스트 형식으로 반환
gen7 = itertools.product('ABCDE')
print(gen7)

print(list(gen7))

# 연산(경우의 수), 2개씩 경우의 수를 표현
gen8 = itertools.product('ABCDE', repeat=2)

# print(len(list(gen8)))
print(list(gen8))
print('*****************************')
print(list(gen8))
--------------------------------------------[result]
< itertools.product object at 0x000002B83200E828 >
[('A',), ('B',), ('C',), ('D',), ('E',)]
[('A', 'A'), ('A', 'B'), ('A', 'C'), ('A', 'D'), ('A', 'E'), ('B', 'A'), ('B', 'B'), ('B', 'C'), ('B', 'D'), ('B', 'E'), ('C', 'A'), ('C', 'B'), ('C', 'C'), ('C', 'D'), ('C', 'E'), ('D', 'A'), ('D', 'B'), ('D', 'C'), ('D', 'D'), ('D', 'E'), ('E', 'A'), ('E', 'B'), ('E', 'C'), ('E', 'D'), ('E', 'E')]
*****************************
[]

--------------------------------------------
--------------------------------------------

# 그룹화
gen9 = itertools.groupby('AAABBCCCCDDEEE')

# print(list(gen9))

# for chr, group in gen9: # 둘중에 한곳만 출력됨
#     print(chr, ' : ', list(group))
print('----------')
for chr, group in gen9: # 둘중에 한곳만 출력됨
    print(chr, ' : ', len(list(group)))    
--------------------------------------------[result]
----------
A  :  3
B  :  2
C  :  4
D  :  2
E  :  3

'Python > Intermediate' 카테고리의 다른 글

[Python] 병행성(Concurrency) - Futures(1)  (0) 2021.05.26
[Python] 병행성(Concurrency) - Coroutine  (0) 2021.05.26
[Python] 병행성(Concurrency) - basic  (0) 2021.05.25
[Python] Decorator  (0) 2021.05.25
[Python] Closure  (0) 2021.05.25