プログラミング原人の進化ログ

プログラミング原人の進化論

オレ プログラミング ベンキョウ スル。マナンダ コト カク。

【Python】リストの要素を独立に変化させたときの全ての組み合わせを求める

何をするのか

わかりにくいタイトルですが、例えばリスト[x1, x2]を考えたときにx1, x2がそれぞれ0, 1, 2のいずれかの値を取るとします。この時、組み合わせの総数は3^2 = 9通りです。
こういった場合に、全ての組み合わせを列挙する方法を考えます。

方針

わかりやすくするためにリストの要素は整数とします。

f:id:programgenjin:20190707115936p:plain

上の例でいうと、取り得る値のリスト[0, 1, 2]を要素の個数分(ここでは2つ)用意して、そこから1つづつ値を取ってくることにします。
これを実現するには直積を利用します。
直積というのは、いくつかの集合から1つづつ元をとってできる全ての組を元とする集合のことです。

実装

pythonで直積を作るにはitertoolsを使うと便利です。itertools.product()は、引数に与えたリストの直積をとってくれます。

import itertools

N = 2  # リストの要素数
lim_lst = [range(3) for _ in range(N)]  # 取り得る値のリストをN個用意
list(itertools.product(*lim_lst))

実行結果

[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]

lim_lstを展開して渡していることに注意。

まとめ

直積を用いればいいと気づいてしまえば簡単でしたが、特にリストの要素数が動的に決まる場合はそうでなければ苦労しそうです。

参考

itertoolsによる順列、組み合わせ、直積のお勉強 - Qiita