itertools
前回、例外処理try…exceptで強制的に例外を発生させるraiseの使い方を紹介しました。
今回はPythonでitertoolsを使った組み合わせ、順列、そして複数のリストの要素の総組み合わせの作成方法を紹介します。
それでは始めていきましょう。
組み合わせ
あるリストの要素から特定の個数を抜き出した組み合わせを作成するには「itertools.combination(リスト, 個数)」とします。
import itertools
a = [1, 2, 3, 4, 5]
combinations = itertools.combinations(a, 2)
print(*combinations)
実行結果
(1, 2) (1, 3) (1, 4) (1, 5) (2, 3) (2, 4) (2, 5)
(3, 4) (3, 5) (4, 5)
ちなみにitertools関数の返り値はイテレータとして返ってくるので、ここでは「*(アスタリスク)」を使ったアンパックを使って値を表示しています。
「*(アスタリスク)」を使ったアンパックに関してはこちらの記事で紹介していますので、よかったらどうぞ。
アンパックせずにprintするとこうなります。
import itertools
a = [1, 2, 3, 4, 5]
combinations = itertools.combinations(a, 2)
print(combinations)
実行結果
<itertools.combinations object at 0x1124db790>
順列
あるリストの要素を特定の個数抜き出し、順列を作成するには「itertools.permutations(リスト, 個数)」とします。
import itertools
a = [1, 2, 3, 4, 5]
permutations = itertools.permutations(a, 2)
print(*permutations)
実行結果
(1, 2) (1, 3) (1, 4) (1, 5) (2, 1) (2, 3) (2, 4)
(2, 5) (3, 1) (3, 2) (3, 4) (3, 5) (4, 1) (4, 2)
(4, 3) (4, 5) (5, 1) (5, 2) (5, 3) (5, 4)
複数のリストの要素の総組み合わせ
複数のリストの要素の総組み合わせを作成するには「itertools.product(リスト1, リスト2, …)」とします。
import itertools
b = [1, 2, 3]
c = [4, 5, 6]
product = itertools.product(b, c)
print(*product)
実行結果
(1, 4) (1, 5) (1, 6) (2, 4) (2, 5) (2, 6) (3, 4) (3, 5) (3, 6)
上の例では2つのリストの総組み合わせを作成していますが、3つ以上でも同様に作成することができます。
import itertools
b = [1, 2, 3]
c = [4, 5, 6]
d = [7, 8, 9]
product = itertools.product(b, c, d)
print(*product)
実行結果
(1, 4, 7) (1, 4, 8) (1, 4, 9) (1, 5, 7) (1, 5, 8) (1, 5, 9)
(1, 6, 7) (1, 6, 8) (1, 6, 9) (2, 4, 7) (2, 4, 8) (2, 4, 9)
(2, 5, 7) (2, 5, 8) (2, 5, 9) (2, 6, 7) (2, 6, 8) (2, 6, 9)
(3, 4, 7) (3, 4, 8) (3, 4, 9) (3, 5, 7) (3, 5, 8) (3, 5, 9)
(3, 6, 7) (3, 6, 8) (3, 6, 9)
イテレータで注意すること
なかなか便利なitertoolsですが、返ってくる値がイテレータということで注意する点があります。
それはそれぞれの値は一回しか取得できないということです。
例えばこんなふうにfor文を使って、イテレータから値を一つ一つ取得していくとします。
import itertools
a = [1, 2, 3, 4, 5]
combinations = itertools.combinations(a, 2)
print("1st round")
for comb in combinations:
print(comb)
実行結果
1st round
(1, 2)
(1, 3)
(1, 4)
(1, 5)
(2, 3)
(2, 4)
(2, 5)
(3, 4)
(3, 5)
(4, 5)
1回目では値がちゃんと取得できます。
もう一つfor文を追加して、もう一度値を取得しようとします。
import itertools
a = [1, 2, 3, 4, 5]
combinations = itertools.combinations(a, 2)
print("1st round")
for comb in combinations:
print(comb)
print("2nd round")
for comb in combinations:
print(comb)
実行結果
1st round
(1, 2)
(1, 3)
(1, 4)
(1, 5)
(2, 3)
(2, 4)
(2, 5)
(3, 4)
(3, 5)
(4, 5)
2nd round
すると2回目は値は取得できませんでした。
これはitertoolsで返ってくる値がイテレータであるため、呼び出されるたびに値を一つずつ返していき、値がなくなると最初に戻るのではなく、何も返さないという処理が行われるためです。
ジェネレータの動きと同じで、ジェネレータはこちらで紹介していますので、よかったらどうぞ。
もし繰り返し使いたい場合はイテレータをリストに変換するのが良いです。
import itertools
a = [1, 2, 3, 4, 5]
combinations = list(itertools.combinations(a, 2))
print("1st round")
for comb in combinations:
print(comb)
print("2nd round")
for comb in combinations:
print(comb)
実行結果
1st round
(1, 2)
(1, 3)
(1, 4)
(1, 5)
(2, 3)
(2, 4)
(2, 5)
(3, 4)
(3, 5)
(4, 5)
2nd round
(1, 2)
(1, 3)
(1, 4)
(1, 5)
(2, 3)
(2, 4)
(2, 5)
(3, 4)
(3, 5)
(4, 5)
次回は太陽電池解析用ライブラリSolcoreを使って太陽光、LED光、レーザー光、ハロゲン光のスペクトルをグラフ化する方法を紹介します。
ではでは今回はこんな感じで。
コメント