# 병렬성(Parallelism) : 여러 컴퓨터가 여러 작업을 동시에 수행 -> 속도
# 병행성(Concurrency) : 한 컴퓨터가 여러일을 동시에 수행
# -> 단일 프로그램 안에서 여러일을 쉽게 해결
# 이터레이터, 제네레이터
# Iterator, Generator
# 파이썬 반복 가능한 타입
# for, collections, text file, List, Dict, Set, Tuple, unpacking, *args
Iterator, Generator - 값을 차례대로 가져올 수 있음
✅ Iterator (이터레이터)
"하나씩 값을 꺼낼 수 있는 객체"
- __iter__()와 __next__() 메서드를 가진 객체
- for 문, next() 함수와 함께 사용 가능
- 값을 직접 기억하고 관리함 (내부 상태)
✅ Generator (제너레이터)
"yield로 값을 순차적으로 만들어내는 특별한 이터레이터"
- yield 키워드로 값을 하나씩 생성 (return 아님)
- 자동으로 __iter__()와 __next__() 구현됨
- 메모리를 덜 쓰고, 필요한 순간에만 값을 생성 (lazy)
# Generator Ex1
def generator_ex1():
print('Start')
yield 'A Point.'
print('continue')
yield 'B Point.'
print('End')
temp = iter(generator_ex1())
print(next(temp))
# Start
# A Point.
print(next(temp))
# continue
# B Point.
# print(next(temp)) # exception
# # End
# # Traceback (most recent call last):
# # print(next(temp))
# # 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 출력 발생
# Start
# continue
# End
temp3 = (x * 3 for x in generator_ex1())
print(type(temp2))
print(type(temp3))
# < class 'list' >
# < class 'generator' >
print(temp2)
print(temp3)
# ['A Point.A Point.A Point.', 'B Point.B Point.B Point.']
# <generator object <genexpr> at 0x7facd8194b30>
for i in temp2: # yield 만 저장되어 출력됨
print(i)
# A Point.A Point.A Point.
# B Point.B Point.B Point.
for i in temp3:
print(i)
# Start
# A Point.A Point.A Point.
# continue
# B Point.B Point.B Point.
# End
for i in temp3:
print(i)
# 더 이상 출력이 되지 않는다, 제너레이터는 한번만 사용가능.
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))
# < generator object square_numbers at 0x000002B832000CA8 > < class 'generator' >
for num in my_nums: # 주석처리하면 b 로 시작하는 for 문이 출력됨.
print('a', num)
# a 1
# a 4
# a 9
# a 16
# a 25
for num in my_nums: # 메모리가 비어 있어서 출력되는게 없음.
print('b', num)
itertools 관련 패키지 모음 - count, takewhile, filterfalse, accumulate, chain, product, groupby
import itertools
# 무한 반복문
gen1 = itertools.count(1, 2.5)
print(type(gen1))
print(gen1)
# < class 'itertools.count' >
# count(1, 2.5)
print(next(gen1))
print(next(gen1))
print(next(gen1))
print(next(gen1))
# 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))
# < class 'itertools.takewhile' >
# < itertools.takewhile object at 0x000002B831FF9E48 >
# 1
for v in gen2:
print(v)
# 1
# 3.5
# 6.0
# 8.5
--------------------------------------------
--------------------------------------------
# 필터 반대, 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))
# A : ['A', 'A', 'A']
# B : ['B', 'B']
# C : ['C', 'C', 'C', 'C']
# D : ['D', 'D']
# E : ['E', 'E', 'E']
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)(4) - Futures(1) (0) | 2021.05.26 |
---|---|
[Python] 병행성(Concurrency)(3) - Coroutine (0) | 2021.05.26 |
[Python] 병행성(Concurrency)(1) - basic (0) | 2021.05.25 |
[Python] 일급함수(4) - Decorator (0) | 2021.05.25 |
[Python] 일급함수(2,3) - Closure (0) | 2021.05.25 |