[Python] product関数を使って多重ループを1つのループにする
多重ループを書くとネストが深くなり、読みにくさが倍増する。
関数を使うなど、ループを浅くする方法はいくつかあるが、ここではPython標準ライブラリのitertoolsライブラリを使う方法を紹介する。
例えば次のようなコードがあったとしよう。
コード 1:
for i in range(3): for j in range(2): print([i, j])
出力 1:
[0, 0] [0, 1] [1, 0] [1, 1] [2, 0] [2, 1]
このコードには二重ループが含まれている。二重ループであればそれほど読みにくさは感じないが、他の処理と組み合わさって三重以上のループになってしまった場合、読みにくさを感じる人も多いのではないか。
そこで、Python標準ライブラリであるitertools
ライブラリに用意されている、product
関数を使って、この二重ループを一重ループにする。
docs.python.org
コード 2:
from itertools import product for i, j in product(range(3), range(2)): print([i, j])
出力 2 (出力1と同じ):
[0, 0] [0, 1] [1, 0] [1, 1] [2, 0] [2, 1]
product
関数は、複数のリストまたはジェネレータを受け取り、それらのすべての組み合わせを生成するジェネレータを返す。これにより、シンプルな二重ループを1つのループに落とすことができる。
同様にして、三重ループも1つのループに落とすことができる。
コード 3(出力結果は省略):
from itertools import product for i, j in product(range(3), range(2), range(4)): print([i, j, k])
product
関数のrepeat
引数に整数を指定すれば、与えたリストまたジェネレータを何個分組み合わせるかを指定できる。下の例では、0から2までを生成するジェネレータを二つ組み合わせて、合計9通りの組み合わせを生成するジェネレータを返している。
コード 4:
from itertools import product for i, j in product(range(3), repeat=2): print([i, j])
出力 4:
[0, 0] [0, 1] [0, 2] [1, 0] [1, 1] [1, 2] [2, 0] [2, 1] [2, 2]
itertools
ライブラリにはproduct
関数の他にも有用な関数が用意されているので、興味を持った方は一度ドキュメントを覗いてみるのがよいと思う。
docs.python.org