itertools — 효율적인 순회를 위한 반복자 함수
itertools — 효율적인 순회를 위한 반복자 함수
itertools 모듈은 반복자에 대한 빠르고 메모리 효율적인 도구를 제공해요. 여러 가지 "반복자 빌딩 블록"들이 있어서, 순수 Python 도구만으로 만든 것보다 더 간결하고 효율적으로, 그리고 메모리를 아끼면서 조합함수(combination)를 만들 수 있어요.
이 모듈의 함수들은 C로 구현돼 있지만, 그 동작은 순수 Python 코드로도 정확히 재현할 수 있습니다. 여기서는 각 함수의 사용법과 특징을 설명할게요.
출처: Python 표준 라이브러리
무한 반복자 (Infinite iterators)
itertools.count(start=0, step=1)—start에서 시작해step씩 증가하는 값을 무한히 만들어 내요. 인덱스나 타임스탬프에 유용합니다.
>>> from itertools import count
>>> for i in count(10, 2):
... if i > 16: break
... print(i)
10
12
14
16
itertools.cycle(iterable)— 이터러블의 요소를 무한히 반복해요. 절전 상태를 저장해 첫 요소에 대한 포인터를 유지합니다.
>>> from itertools import cycle
>>> list(islice(cycle('AB'), 5))
['A', 'B', 'A', 'B', 'A']
itertools.repeat(object, times=None)—object를 무한히, 또는 지정된times횟수만큼 반복해요.repeat와zip을 함께 쓰면, 제네레이터에 곱셈된 상수로 마치 리스트의 각 항목에 같은 값을 곱하는 듯한 효과를 줍니다.
최단 입력을 기준으로 종료되는 반복자 (Iterators terminating on the shortest input sequence)
itertools.accumulate(iterable, func=operator.add, *, initial=None)— 누적 합계(또는 이항 함수의 누적 결과)를 만들어 내요.
>>> from itertools import accumulate
>>> list(accumulate([1, 2, 3, 4, 5]))
[1, 3, 6, 10, 15]
itertools.batched(iterable, n)— 이터러블을n개 크기의 튜플로 묶어 만들어 내요. 마지막 배치는 더 짧을 수 있어요.
>>> list(batched('ABCDEFG', 3))
[('A', 'B', 'C'), ('D', 'E', 'F'), ('G',)]
itertools.chain(*iterables)— 여러 이터러블을 순서대로 이어 붙여요.
>>> list(chain('ABC', 'DEF'))
['A', 'B', 'C', 'D', 'E', 'F']
-
itertools.chain.from_iterable(iterable)— 이터러블들을 이어 붙이는 생성자.chain(*iter)과 동일하지만 인자가 아닌 이터러블 하나를 받아요. -
itertools.compress(data, selectors)—selectors가 참인 위치의data요소만 걸러 내요.
>>> list(compress('ABCDEF', [1, 0, 1, 0, 1, 1]))
['A', 'C', 'E', 'F']
itertools.dropwhile(predicate, iterable)—predicate가 참인 동안 요소를 버리고, 처음 거짓이 되는 지점부터 나머지를 만들어 내요.
>>> list(dropwhile(lambda x: x < 5, [1, 4, 6, 3, 8]))
[6, 3, 8]
-
itertools.filterfalse(predicate, iterable)—predicate가 거짓인 요소만 만들어 내요 (filter의 반대). -
itertools.groupby(iterable, key=None)— 이터러블을 키 함수의 결과로 그룹화한(key, group)쌍을 만들어 내요. 주의: 그룹을 만들려면 입력이 키에 따라 이미 정렬돼 있어야 해요.
>>> [k for k, g in groupby('AAAABBBCCDAABBB')]
['A', 'B', 'C', 'D', 'A', 'B']
itertools.islice(iterable, stop)/itertools.islice(iterable, start, stop, step)— 이터러블의 슬라이스를 만들어 내요. 양의 인덱스만 지원합니다.
>>> list(islice('ABCDEFG', 2, 6, 2))
['C', 'E']
itertools.pairwise(iterable)— 연속된 겹치는 쌍을 만들어 내요.
>>> list(pairwise('ABCDEF'))
[('A', 'B'), ('B', 'C'), ('C', 'D'), ('D', 'E'), ('E', 'F')]
-
itertools.starmap(function, iterable)—function(*item)처럼 이터러블의 각 항목을 풀어서 함수를 호출한 결과를 만들어 내요. -
itertools.takewhile(predicate, iterable)—predicate가 참인 동안 요소를 만들어 내고, 처음 거짓이 되면 멈춰요. -
itertools.tee(iterable, n=2)— 하나의 이터러블에서n개의 독립적인 반복자 복사본을 만들어 내요. -
itertools.zip_longest(*iterables, fillvalue=None)— 여러 이터러블을 가장 긴 것에 맞춰서 묶어요. 짧은 쪽은fillvalue로 채워요 (내장zip은 짧은 쪽에 맞춰서 멈춰요).
조합 생성자 (Combinatoric iterators)
itertools.product(*iterables, repeat=1)— 카테시안 곱(데카르트 곱)을 만들어 내요.
>>> list(product('AB', repeat=2))
[('A', 'A'), ('A', 'B'), ('B', 'A'), ('B', 'B')]
itertools.permutations(iterable, r=None)— 요소들을 길이r로 연속 나열한 순열을 만들어 내요.
>>> list(permutations('ABC', 2))
[('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')]
itertools.combinations(iterable, r)— 요소들을 길이r로 조합(순서 무시)해 만들어 내요.
>>> list(combinations('ABC', 2))
[('A', 'B'), ('A', 'C'), ('B', 'C')]
itertools.combinations_with_replacement(iterable, r)— 요소 중복을 허용한 조합을 만들어 내요.
>>> list(combinations_with_replacement('ABC', 2))
[('A', 'A'), ('A', 'B'), ('A', 'C'), ('B', 'B'), ('B', 'C'), ('C', 'C')]
순서 규칙을 표로 요약하면:
| 조합 연산 | 요소가 순서 있는지 | 요소 반복 여부 |
|---|---|---|
product() |
네 | 네 |
permutations() |
네 | 아니오 |
combinations(r) |
아니오 | 아니오 |
combinations_with_replacement(r) |
아니오 | 네 |
레시피 (Recipes)
itertools 문서는 이 함수들을 조합해 파워풀한 도구를 만드는 레시피를 포함해요. 예를 들어:
iter_index(iterable, value, start=0, stop=None)— 값이 나타나는 인덱스들을 순회.sieve(n)— n까지의 소수를 찾는 에라토스테네스의 체.batched기반의grouper(iterable, n, *, incomplete='fill', fillvalue=None)— 요소들을 고정 크기 그룹으로 묶기.powerset(iterable)— 모든 부분집합(멱집합)을 만드는 레시피.
대표적인 powerset 레시피:
from itertools import chain, combinations
def powerset(iterable):
"powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
s = list(iterable)
return chain.from_iterable(combinations(s, r) for r in range(len(s) + 1))
더 알아보기
- Python 표준 라이브러리의
functools,operator모듈 - Python 공식 문서: itertools