概要(permutations は「順番を考慮した並べ方」を遅延生成で作る)
itertools.permutations は、イテラブルの要素を「順番を考慮して並べ替えたすべての並び(順列)」を順に返すイテレータです。長さ r を指定でき、結果はタプルで返されます。多重ループを書かずに全並びを列挙でき、結果は遅延生成されるため巨大な組み合わせでも安全に扱えます。
from itertools import permutations
items = ["A", "B", "C"]
for p in permutations(items): # r を省略 → 全要素の順列(r=3)
print(p) # ('A','B','C'), ('A','C','B'), ...
Python基本の使い方(ここが重要)
長さ r の指定(r を省略すると全要素)
r を指定すると、元の要素から r 個を「順番あり」で並べた順列を返します。r を省略すると、元の長さすべて(len(iterable))の順列です。
from itertools import permutations
for p in permutations([1, 2, 3], 2):
print(p) # (1,2), (1,3), (2,1), (2,3), (3,1), (3,2)
Python返り値はタプル。必要なら文字列や数字へ変換
並びはタプルで返されます。表示や利用に応じて join や計算へ変換します。
from itertools import permutations
for p in permutations("ABC", 3):
print("".join(p)) # 'ABC', 'ACB', 'BAC', ...
Python遅延生成(メモリに全展開しない)
permutations は1個ずつ作るため、巨大な並びでも「必要な分だけ」取り出せます。list(…) で全展開するとメモリが爆発しやすいので注意し、基本は for で流します。
from itertools import permutations, islice
it = permutations(range(1000), 3)
for p in islice(it, 10): # 先頭10件だけ見る
print(p)
Python重要ポイントの深掘り(サイズ計算・重複要素・比較対象)
通り数(サイズ)は階乗や置換で爆発する
- 全要素の順列数は n!(n の階乗)。
- 長さ r の順列数は nPr = n × (n-1) × … × (n-r+1)。
要素数が少し増えるだけで通り数が急増するため、実務では「打ち切り」「条件で絞り込み」が必須です。
import math
n = 6
print(math.factorial(n)) # 720(6!)
def nPr(n, r):
out = 1
for k in range(r): out *= (n - k)
return out
print(nPr(10, 3)) # 720(10P3)
Python入力に重複があると、重複した順列が出る
permutations は入力の各要素を位置で区別します。入力に同じ値が複数あると、重複結果が出ます。重複排除したい場合は一度ソートしてから、集合や辞書で弾く、あるいは独自フィルタを噛ませます。
from itertools import permutations
items = ["A", "A", "B"]
uniq = set("".join(p) for p in permutations(items, 2))
print(sorted(uniq)) # 重複排除した並び ['AA', 'AB', 'BA']
Pythoncombinations と product との違い
- combinations は「順番を無視した取り合わせ」。(A,B) と (B,A) は同じとして1通り。
- permutations は「順番あり」。(A,B) と (B,A) は別通り。
- product は「直積」。別の集合を組み合わせる全通り(重複選択も可能)。
用途に応じて使い分けると、無駄な列挙を避けられます。
実務での使いどころ(並び検討・探索・テストケース)
順番が意味を持つ並べ替えの網羅(並べ順最適化の下準備)
タスク順序、処理パイプライン、UI 配置など、「順序によって結果が変わる」ものの当たり検討に向きます。評価関数で絞りながら逐次処理しましょう。
from itertools import permutations
tasks = ["parse", "filter", "export"]
best = None
best_score = float("-inf")
def score(order):
# ダミー評価。実務では計測や制約を入れる
return 100 - 10 * order.index("export")
for order in permutations(tasks):
s = score(order)
if s > best_score:
best, best_score = order, s
print(best, best_score)
Pythonパス・ファイル名の順列生成(少数なら一括、巨大なら条件絞り)
短い接頭辞・拡張子・日付などを並べ替えながら探索するケースで便利です。件数が多くなる場合は、早めの条件判定で落としていきます。
from itertools import permutations
for name in permutations(["report", "2025-12-15", "final"], 2):
print("_".join(name)) # 'report_2025-12-15', 'report_final', ...
Pythonテスト ID・シナリオ順列(部分取り出しで現実的に)
大量になるため、islice で一部サンプルだけ採取する、ランダムサンプリングする、制約で削減するのが定石です。
from itertools import permutations, islice
import random
cases = permutations("ABCDE", 3)
sample = list(islice(cases, 20)) # 先頭20件だけ
random.shuffle(sample)
for c in sample[:5]:
print(c)
Python例題で身につける(定番から一歩先まで)
例題1:3桁の並びで条件を満たすものだけ列挙
from itertools import permutations
def valid_codes():
for a, b, c in permutations(range(5), 3):
# 隣り合う差が1以下、合計が奇数などの条件例
if abs(a - b) <= 1 and abs(b - c) <= 1 and ((a + b + c) % 2 == 1):
yield (a, b, c)
for code in list(valid_codes())[:10]:
print(code)
Python例題2:旅行ルートの総当たり(簡易版)
from itertools import permutations
cities = ["Tokyo", "Osaka", "Nagoya", "Fukuoka"]
def route_cost(route):
# ダミーコスト。距離テーブルがある想定で計算する
return len(route) * 10
best, best_cost = None, float("inf")
for route in permutations(cities):
cost = route_cost(route)
if cost < best_cost:
best, best_cost = route, cost
print("best:", best, best_cost)
Python例題3:重複入力の重複排除順列(ユニークだけ取りたい)
from itertools import permutations
items = ["A", "A", "B", "C"]
def unique_perms(iterable, r):
seen = set()
for p in permutations(sorted(iterable), r):
if p not in seen:
seen.add(p)
yield p
for p in unique_perms(items, 3):
print(p)
Python例題4:パスワード候補(英字+数字の並び)を一部だけ生成
from itertools import permutations
import string
letters = string.ascii_lowercase[:4] # 'a','b','c','d'
digits = "0123"
for cand in permutations(letters + digits, 3):
s = "".join(cand)
if s[0].isalpha() and any(ch.isdigit() for ch in s):
print(s)
break # 条件を満たす最初の1件だけ
Pythonまとめ
itertools.permutations は「順番を考慮した並べ替え(順列)」を遅延生成で安全に列挙する基本ツールです。r 指定で部分順列、返り値はタプル、巨大化しやすいのでサイズ見積もりと早期絞り込みが要。入力に重複があると重複結果が出る点に注意し、必要ならユニーク化を組み合わせる。combinations(順番なし)や product(直積)と正しく使い分ければ、並べ順の網羅、探索、テスト列挙が短く、読みやすく、堅牢に書けます。
