組み合わせや順列の列挙に便利なitertoolsの機能

確率や統計だったり、全パターン列挙などをする場合に便利な関数群を一部紹介。
これらの関数を使うことで複数のネストしたループを作らなくてすんで大変便利です。

組み合わせ combinations

例:5枚の数字カード[0..4]から3枚引いた時の取れるカードの組み合わせ。順番は関係なし

>>> import itertools
>>> list(itertools.combinations(range(5), 3))
[(0, 1, 2), (0, 1, 3), (0, 1, 4), (0, 2, 3), (0, 2, 4), 
  (0, 3, 4), (1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)]

順列 permutations

例:4枚の数字カード[0..3]の並び順のパターン。

>>> import itertools
>>> list(itertools.permutations(range(4)))
[(0, 1, 2, 3), (0, 1, 3, 2), (0, 2, 1, 3), (0, 2, 3, 1), 
....
(3, 1, 0, 2), (3, 1, 2, 0), (3, 2, 0, 1), (3, 2, 1, 0)]   #24パターン

例:4枚の数字カードから2枚取る場合の並び順のパターン。

>>> list(itertools.permutations(range(4), 2))
[(0, 1), (0, 2), ... (3, 2)]  #12パターン

直積 product

デカルト積。for ループの入れ子をせずに全パターンを網羅するときに便利。

例:剣はw1, w2, w3の3種類。盾はs1,s2,s3,s4の4種類。鎧はa1, a2の2種類。この3つの装備の全パターンを網羅。

>>> import itertools
>>> swords=['w1', 'w2', 'w3']
>>> shields=['s1','s2','s3','s4']
>>> armors=['a1', 'a2']
>>> list(itertools.product(swords, shields, armors))
[('w1', 's1', 'a1'), ('w1', 's1', 'a2'), ('w1', 's2', 'a1'),
...
, ('w3', 's4', 'a2')]   #24パターン

例:サイコロを4回ふった時の出目の全パターン
repeatを使うと、集合に対する直積を指定していることになる。下記の例でいうと、
itertools.product(range(1,7), repeat=4)と、
itertools.product(range(1,7), range(1,7), range(1,7), range(1,7))
は同じ意味になる。

>>> list(itertools.product(range(1,7), repeat=4))
[(1, 1, 1, 1), (1, 1, 1, 2), (1, 1, 1, 3), (1, 1, 1, 4), (1, 1, 1, 5), 
...
  , (6, 6, 6, 5), (6, 6, 6, 6)]  #1296パターン

他にもたくさんあるので公式ドキュメントを参考に。
10.1. itertools — 効率的なループ実行のためのイテレータ生成関数 — Python 3.4.3 ドキュメント

関連記事:

組み合わせや順列の列挙に便利なitertoolsの機能」への3件のフィードバック

  1. ピンバック: pythonでループのネストを減らす定石 itertools | Python Snippets

  2. shoka

    最初のコードの1行目に誤植が見られます
    iteretools→itertoolsですね。
    ご査収ください。

    返信
    1. python-tksssk 投稿作成者

      ありがとうございます!修正いたしました。

      返信

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)