うそだぁ。
1 >>> from itertools import combinations
2 >>> combinations([3, 4, 1])
3 Traceback (most recent call last):
4 File "<stdin>", line 1, in <module>
5 TypeError: Required argument 'r' (pos 2) not found
6 >>> list(combinations([3, 4, 1], 3))
7 [(3, 4, 1)]
8 >>> list(combinations([3, 4, 1], 2))
9 [(3, 4), (3, 1), (4, 1)]
と思ったら。
あ、 combinations でなくて permutations 限定の話か、これ。
組み合わせも順列も、それこそ高校時代に習ったままの記憶しかなく、たまたま仕事でも必要になったことがなかったので、たぶん高校生向けと思われるサイトをみてようやく思い出した、という次第である。
それで気付いたことなのだが、「学生向けにわかりやすい説明」と思われる、「組み合わせは並べない、順列は並べる」という説明は、ビミョーだ、ってことだ。
確かに「m 個から n 個選ぶ組み合わせ」「m 個から n 個選んだ n 個の並べ方」という問題を基準に考えればこの説明は「わかりやすい」のだけれど、同じ「並べる/並べない」という言葉で「真逆の雰囲気の説明」が出来てしまうのよ。Python のクックブックがまさにそれ。
まず組み合わせ(combinations)の説明:
そして、組み合わせが「順序を保つ」ことを説明し、順列(permutationss)の説明が続く:
少し混乱してこないか? どっちが並べて、どっちが並べてない? どっちも並べてるんじゃない? とか。
冷静に、じっくりゆっくり考えればもちろんこれ、何一つ難しいことはないのね。「(3, 4, 1) と (1, 3, 4) が同じ意味かそうでないか」だけの差なんだから。それをなまじ「並べる/並べない」という脳内イメージを固定してしまいがちな言葉で説明しようとすると、こういう妙な言葉のトラップに引っかかる。
さて。ではなんで combinations は引数 r の省略を許さないのか。これが一瞬わからなくて、わかったときには、あぁ、バカだ、ワタシは、と思った。そりゃそーでしょーよ。「10 個から 10 個選ぶ組み合わせ」なんて計算したって意味ねーじゃん。