Python Itertools 모듈

itertools 모듈은 반복자 (예: 리스트 또는 딕셔너리) 를 처리할 때 빠르고 메모리 효율적으로 작동하도록 설계된 도구 모음입니다.

Python 3 문서에서 발췌

이 모듈은 그 자체로 또는 조합하여 유용한 빠르고 메모리 효율적인 도구들의 핵심 세트를 표준화합니다. 이 도구들은 함께 "반복자 대수 (iterator algebra)"를 구성하여 순수 Python 에서 특수화된 도구를 간결하고 효율적으로 만들 수 있게 합니다.

itertools 모듈은 표준 라이브러리에 포함되어 있으므로 가져와야 합니다. 일부 예제에서는 operator 모듈도 사용합니다.

import itertools
import operator

accumulate()

함수의 결과를 반환하는 반복자를 만듭니다.

itertools.accumulate(iterable[, func])

예시:

data = [1, 2, 3, 4, 5]
# 곱셈 함수로 누적 계산
result = itertools.accumulate(data, operator.mul)
for each in result:
    print(each)
1
2
6
24
120

operator.mul 은 두 숫자를 받아 곱합니다:

operator.mul(1, 2)
# 2

operator.mul(2, 3)
# 6

operator.mul(6, 4)
# 24

operator.mul(24, 5)
# 120

함수를 전달하는 것은 선택 사항입니다:

data = [5, 2, 6, 4, 5, 9, 1]
# 함수 없이 누적 계산은 덧셈이 기본값입니다
result = itertools.accumulate(data)
for each in result:
    print(each)
5
7
13
17
22
31
32

함수가 지정되지 않으면 항목들이 합산됩니다:

5
5 + 2 = 7
7 + 6 = 13
13 + 4 = 17
17 + 5 = 22
22 + 9 = 31
31 + 1 = 32

combinations()

반복 가능한 객체와 정수를 받습니다. 이는 r 개의 요소를 가진 모든 고유한 조합을 생성합니다.

itertools.combinations(iterable, r)

예시:

shapes = ['circle', 'triangle', 'square',]
# 2 개 요소의 모든 조합 생성
result = itertools.combinations(shapes, 2)
for each in result:
    print(each)
('circle', 'triangle')
('circle', 'square')
('triangle', 'square')

combinations_with_replacement()

combinations() 와 동일하지만, 개별 요소가 한 번 이상 반복되는 것을 허용합니다.

itertools.combinations_with_replacement(iterable, r)

예시:

shapes = ['circle', 'triangle', 'square']
# 반복을 허용하는 조합 생성
result = itertools.combinations_with_replacement(shapes, 2)
for each in result:
    print(each)
('circle', 'circle')
('circle', 'triangle')
('circle', 'square')
('triangle', 'triangle')
('triangle', 'square')
('square', 'square')

count()

숫자 start 부터 시작하여 균등한 간격의 값을 반환하는 반복자를 만듭니다.

itertools.count(start=0, step=1)

예시:

# 10 부터 시작하여 3 씩 증가하며 카운트
for i in itertools.count(10,3):
    print(i)
    if i > 20:
        break
10
13
16
19
22

cycle()

이 함수는 반복 가능한 객체를 끝없이 순환합니다.

itertools.cycle(iterable)

예시:

colors = ['red', 'orange', 'yellow', 'green', 'blue', 'violet']
# 색상을 무한히 순환
for color in itertools.cycle(colors):
    print(color)
red
orange
yellow
green
blue
violet
red
orange

반복 가능한 객체의 끝에 도달하면 처음부터 다시 시작합니다.

chain()

일련의 반복 가능한 객체들을 받아 하나의 긴 반복 가능한 객체로 반환합니다.

itertools.chain(*iterables)

예시:

colors = ['red', 'orange', 'yellow', 'green', 'blue']
shapes = ['circle', 'triangle', 'square', 'pentagon']
# 여러 반복 가능한 객체를 하나로 연결
result = itertools.chain(colors, shapes)
for each in result:
    print(each)
red
orange
yellow
green
blue
circle
triangle
square
pentagon

compress()

다른 반복 가능한 객체를 사용하여 하나의 반복 가능한 객체를 필터링합니다.

itertools.compress(data, selectors)

예시:

shapes = ['circle', 'triangle', 'square', 'pentagon']
selections = [True, False, True, False]
# 부울 선택에 따라 도형 필터링
result = itertools.compress(shapes, selections)
for each in result:
    print(each)
circle
square

dropwhile()

술어가 참인 동안 반복 가능한 객체에서 요소를 건너뛰고, 그 이후에는 모든 요소를 반환하는 반복자를 만듭니다.

itertools.dropwhile(predicate, iterable)

예시:

data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1]
# 조건이 참인 동안 요소를 건너뛰고 나머지 모두 반환
result = itertools.dropwhile(lambda x: x<5, data)
for each in result:
    print(each)
5
6
7
8
9
10
1

filterfalse()

반복 가능한 객체에서 술어가 거짓인 요소만 필터링하여 반환하는 반복자를 만듭니다.

itertools.filterfalse(predicate, iterable)

예시:

data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1]
# 술어가 거짓인 요소 반환
result = itertools.filterfalse(lambda x: x<5, data)
for each in result:
    print(each)
5
6
7
8
9
10

groupby()

간단히 말해, 이 함수는 항목들을 그룹화합니다.

itertools.groupby(iterable, key=None)

예시:

robots = [
    {"name": "blaster", "faction": "autobot"},
    {"name": "galvatron", "faction": "decepticon"},
    {"name": "jazz", "faction": "autobot"},
    {"name": "metroplex", "faction": "autobot"},
    {"name": "megatron", "faction": "decepticon"},
    {"name": "starcream", "faction": "decepticon"},
]
# 진영별로 로봇 그룹화 (올바른 그룹화를 위해 반복 가능한 객체는 정렬되어야 함)
for key, group in itertools.groupby(robots, key=lambda x: x['faction']):
    print(key)
    print(list(group))
autobot
[{'name': 'blaster', 'faction': 'autobot'}]
decepticon
[{'name': 'galvatron', 'faction': 'decepticon'}]
autobot
[{'name': 'jazz', 'faction': 'autobot'}, {'name': 'metroplex', 'faction': 'autobot'}]
decepticon
[{'name': 'megatron', 'faction': 'decepticon'}, {'name': 'starcream', 'faction': 'decepticon'}]

islice()

이 함수는 슬라이스 (slices) 와 매우 유사합니다. 반복 가능한 객체의 일부를 잘라낼 수 있게 해줍니다.

itertools.islice(iterable, start, stop[, step])

예시:

colors = ['red', 'orange', 'yellow', 'green', 'blue',]
# 반복 가능한 객체를 슬라이스하여 처음 2 개 요소 가져오기
few_colors = itertools.islice(colors, 2)
for each in few_colors:
    print(each)
red
orange

permutations()

itertools.permutations(iterable, r=None)

예시:

alpha_data = ['a', 'b', 'c']
# 요소들의 모든 순열 생성
result = itertools.permutations(alpha_data)
for each in result:
    print(each)
('a', 'b', 'c')
('a', 'c', 'b')
('b', 'a', 'c')
('b', 'c', 'a')
('c', 'a', 'b')
('c', 'b', 'a')

product()

일련의 반복 가능한 객체들로부터 카테시안 곱 (Cartesian products) 을 생성합니다.

num_data = [1, 2, 3]
alpha_data = ['a', 'b', 'c']
# 반복 가능한 객체들의 카테시안 곱 생성
result = itertools.product(num_data, alpha_data)
for each in result:
    print(each)
(1, 'a')
(1, 'b')
(1, 'c')
(2, 'a')
(2, 'b')
(2, 'c')
(3, 'a')
(3, 'b')
(3, 'c')

repeat()

이 함수는 객체를 계속해서 반복합니다. 단, times 인수가 지정되면 횟수가 제한됩니다.

itertools.repeat(object[, times])

예시:

# 객체를 3 번 반복
for i in itertools.repeat("spam", 3):
    print(i)
spam
spam
spam

starmap()

반복 가능한 객체에서 얻은 인수를 사용하여 함수를 계산하는 반복자를 만듭니다.

itertools.starmap(function, iterable)

예시:

data = [(2, 6), (8, 4), (7, 3)]
# 각 튜플의 언패킹된 인수에 함수 적용
result = itertools.starmap(operator.mul, data)
for each in result:
    print(each)
12
32
21

takewhile()

dropwhile() 의 반대입니다. 술어가 참인 동안 반복 가능한 객체에서 요소를 반환하는 반복자를 만듭니다.

itertools.takewhile(predicate, iterable)

예시:

data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1]
# 조건이 참인 동안 요소들을 가져오고, 그 후 중단
result = itertools.takewhile(lambda x: x<5, data)
for each in result:
    print(each)
1
2
3
4

tee()

단일 반복 가능한 객체로부터 n 개의 독립적인 반복자를 반환합니다.

itertools.tee(iterable, n=2)

예시:

colors = ['red', 'orange', 'yellow', 'green', 'blue']
# 반복 가능한 객체를 두 개의 독립적인 반복자로 분할
alpha_colors, beta_colors = itertools.tee(colors)
for each in alpha_colors:
    print(each)
red
orange
yellow
green
blue
colors = ['red', 'orange', 'yellow', 'green', 'blue']
alpha_colors, beta_colors = itertools.tee(colors)
for each in beta_colors:
    print(each)
red
orange
yellow
green
blue

zip_longest()

각 반복 가능한 객체에서 요소를 집계하는 반복자를 만듭니다. 반복 가능한 객체들의 길이가 다르면, 누락된 값은 fillvalue로 채워집니다. 가장 긴 반복 가능한 객체가 소진될 때까지 반복이 계속됩니다.

itertools.zip_longest(*iterables, fillvalue=None)

예시:

colors = ['red', 'orange', 'yellow', 'green', 'blue',]
data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10,]
# 반복 가능한 객체들을 묶고, 누락된 값은 None 으로 채움
for each in itertools.zip_longest(colors, data, fillvalue=None):
    print(each)
('red', 1)
('orange', 2)
('yellow', 3)
('green', 4)
('blue', 5)
(None, 6)
(None, 7)
(None, 8)
(None, 9)
(None, 10)

관련 링크