2015年11月14日

itertools.combinations で2重ループ

itertools には痒いところに手が届く便利ツールが多くあります。今回は itertools.combinations() について紹介します。


まず次の要件を満たすソースコードを、range によるループで記述してみます。

  • compare_files() は2つのファイルを比較する
  • files は比較すべきファイル名のリスト
  • ファイル名の全ての組み合わせについて、compare_file()を行う
# ファイル名のリスト
files = ['a.txt', 'b.txt', 'c.txt', 'd.txt']

for i in range(len(files)):  # 左引数のループ
    for j in range(i + 1, len(files)):  # 右引数のループ
        compare_files(files[i], files[j])

何とも野暮ったい2重ループですね。Pythonicなソースコードには程遠いです。
ここで itertools.combinations を使うと、ループ文を一気にエレガントにすることができます。
from itertools import combinations
files = ['a.txt', 'b.txt', 'c.txt', 'd.txt']

for i, j in combinations(files, 2):
    compare_files(i, j)
itertools.combinations を使うことで、2重ループと[]によるリストへのアクセスを無くすことができました。これならばPythonicだと胸を張れるのではないでしょうか。

頻繁に使う関数ではありませんが、2重ループを書いた時にこのツールのことを思い出すと、幸せになれるかもしれません。
また、itertools.combinations には兄弟分として itertools.permutations と itertools.combinations_with_replacement というのもあります。使い方はほぼ同じですが、作られるループが微妙に異なります。合わせて知っておくと良いかと思います。

0 件のコメント:

コメントを投稿