Python の itertools 入門

itertools は、イテレータを効率的に扱うための標準ライブラリです。メモリ効率の良いイテレータを簡単に作成でき、データ処理やアルゴリズムの実装に役立ちます。

無限イテレータ

終わりのないシーケンスを生成する関数です。

from itertools import count, cycle, repeat

# count: 無限カウント
for n in count(10, 3):  # 10から3ずつ増加
    if n > 20:
        break
    print(n, end=" ")
# 10 13 16 19

# cycle: 要素を無限に繰り返す
colors = cycle(["R", "G", "B"])
for i, c in enumerate(colors):
    if i >= 6:
        break
    print(c, end=" ")
# R G B R G B

# repeat: 同じ値を繰り返す
for x in repeat("Hi", 3):
    print(x, end=" ")
# Hi Hi Hi

終端イテレータ

イテラブルを変換・結合する関数です。

from itertools import chain, islice, takewhile, dropwhile

# chain: 複数のイテラブルを連結
result = list(chain([1, 2], [3, 4], [5]))
print(result)  # [1, 2, 3, 4, 5]

# islice: スライス操作
result = list(islice(range(100), 5, 10))
print(result)  # [5, 6, 7, 8, 9]

# takewhile: 条件を満たす間だけ取得
result = list(takewhile(lambda x: x < 5, [1, 3, 5, 2, 1]))
print(result)  # [1, 3]

# dropwhile: 条件を満たす間はスキップ
result = list(dropwhile(lambda x: x < 5, [1, 3, 5, 2, 1]))
print(result)  # [5, 2, 1]

フィルタリングと選択

from itertools import filterfalse, compress

# filterfalse: 条件に合わないものを選択
evens = list(filterfalse(lambda x: x % 2, range(10)))
print(evens)  # [0, 2, 4, 6, 8]

# compress: セレクタでフィルタリング
data = ["A", "B", "C", "D"]
selectors = [1, 0, 1, 0]
result = list(compress(data, selectors))
print(result)  # ['A', 'C']

グルーピング

from itertools import groupby

# groupby: 連続する同じキーでグループ化
data = [("A", 1), ("A", 2), ("B", 3), ("B", 4), ("A", 5)]
for key, group in groupby(data, lambda x: x[0]):
    print(f"{key}: {list(group)}")
# A: [('A', 1), ('A', 2)]
# B: [('B', 3), ('B', 4)]
# A: [('A', 5)]

注意:groupby は連続する要素のみをグループ化します。全体をグループ化したい場合は、事前にソートしてください。

組み合わせ生成

from itertools import product, permutations, combinations

# product: 直積(デカルト積)
result = list(product("AB", [1, 2]))
print(result)  # [('A', 1), ('A', 2), ('B', 1), ('B', 2)]

# permutations: 順列
result = list(permutations("ABC", 2))
print(result)  # [('A', 'B'), ('A', 'C'), ('B', 'A'), ...]

# combinations: 組み合わせ
result = list(combinations("ABC", 2))
print(result)  # [('A', 'B'), ('A', 'C'), ('B', 'C')]

累積処理

from itertools import accumulate
import operator

# 累積和
result = list(accumulate([1, 2, 3, 4, 5]))
print(result)  # [1, 3, 6, 10, 15]

# 累積積
result = list(accumulate([1, 2, 3, 4], operator.mul))
print(result)  # [1, 2, 6, 24]

よく使う組み合わせ

関数用途
chainリストの連結
isliceスライス(無限イテレータにも使える)
groupby連続要素のグループ化
combinations組み合わせ生成

itertools の関数はすべてイテレータを返すため、メモリ効率が良く、大量のデータ処理に適しています。