Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

Python辞典

  1. トップページ
  2. Python辞典
  3. itertools.product() / itertools.permutations() / itertools.combinations()

itertools.product() / itertools.permutations() / itertools.combinations()

『itertools.product()』は複数のイテラブルの直積(デカルト積)を生成します。『itertools.permutations()』は順列(順序あり・重複なし)、『itertools.combinations()』は組み合わせ(順序なし・重複なし)を生成します。これらは結果をメモリに保持せず遅延評価で生成するため、大量の組み合わせも効率的に処理できます

構文
import itertools

# 直積(デカルト積)
itertools.product(*iterables, repeat=1)

# 順列(重複なし)
itertools.permutations(iterable, r=None)

# 組み合わせ(重複なし)
itertools.combinations(iterable, r)

# 組み合わせ(重複あり)
itertools.combinations_with_replacement(iterable, r)
関数一覧
関数概要
product(*iterables, repeat=1)複数のイテラブルの直積をタプルで生成する。repeatで同一イテラブルを繰り返す。
permutations(iterable, r)r個の要素の順列をすべて生成する。rを省略すると全要素の順列。
combinations(iterable, r)r個の要素の組み合わせをすべて生成する(重複なし)。
combinations_with_replacement(iterable, r)r個の要素の組み合わせをすべて生成する(重複あり)。
サンプルコード
import itertools

# product: 直積(すべての組み合わせ)
sizes = ['S', 'M', 'L']
colors = ['赤', '青']
result = list(itertools.product(sizes, colors))
print(result)
# [('S', '赤'), ('S', '青'), ('M', '赤'), ('M', '青'), ('L', '赤'), ('L', '青')]

# product: repeatで同一リストの直積(サイコロ2個)
dice = list(itertools.product(range(1, 7), repeat=2))
print(len(dice))    # 36(6×6の全組み合わせ)
print(dice[:3])     # [(1, 1), (1, 2), (1, 3)]

# permutations: 順列(順序あり・重複なし)
letters = ['A', 'B', 'C']
perms = list(itertools.permutations(letters, 2))
print(perms)
# [('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')]

# permutations: 全要素の順列
all_perms = list(itertools.permutations([1, 2, 3]))
print(len(all_perms))   # 6(3! = 6)

# combinations: 組み合わせ(順序なし・重複なし)
combs = list(itertools.combinations([1, 2, 3, 4], 2))
print(combs)
# [(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]

# combinations_with_replacement: 重複を許す組み合わせ
combs_rep = list(itertools.combinations_with_replacement(['A', 'B', 'C'], 2))
print(combs_rep)
# [('A', 'A'), ('A', 'B'), ('A', 'C'), ('B', 'B'), ('B', 'C'), ('C', 'C')]
概要

これらの関数はすべてタプルのイテレータを返します。要素数が多くなると生成される組み合わせ数は爆発的に増加するため注意が必要です。例えばn個からr個を選ぶ順列の数はP(n,r) = n!/(n-r)!、組み合わせの数はC(n,r) = n!/(r!(n-r)!)となります。

『product()』のrepeatオプションを使うと、同じイテラブルを複数回使った直積を効率的に生成できます。ネストしたforループで同じ結果を得ることもできますが、productを使う方が簡潔に書けます。ブルートフォース探索やテストケースの自動生成などで活用されます。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。