半日もかけてしまった……今日がんばって作ったものを公開するぜ。
今回作りたいのは重複順列を生成するプログラムだ。
[True, False] 2
を与えると……
[True, True]
[True, False]
[False, True]
[False, False]
これを生成してくれるやつね。

ぶっちゃけこれをやってくれるライブラリはあるんだけどな。
# これでイイ。
import itertools
for x in itertools.product([True, False], repeat=2):
    print(x)
でもまあコレを見本として、自分で作ってみよか。



こんな感じの考え方で。




def my_product(a, n):

    # nぶんのリストを用意します。 [None, None, None] ここにTrue Falseを詰めていきます。
    lis = [None for i in range(n)]
    cursor = -1
    cursor_max = len(lis) - 1

    def foo(lis, cursor):

        for i in a:

            # 1階層もぐって1個詰める。
            cursor += 1
            lis[cursor] = i

            # 最深部だったら出力して1階層戻る。
            if cursor == cursor_max:
                print(lis)
                cursor -= 1

            # 次の階層へ。
            else:
                lis, cursor = foo(lis, cursor)

        # forが終わるとき、1階層戻る。
        cursor -= 1
        return lis, cursor

    foo(lis, cursor)

my_product([True, False], 2)
できた。



すげえ苦労した。ガチ半日。再帰関数を作るのがめちゃむず。普通プログラムのエラーを理解するときは上から一行ずつ追っていくわけだが、再起はそうはいかないから……。最近じゃいちばん書けてテンション上がった python だったぜ。冒頭で itertools.product を挙げているけれど、実はそれと同等のものは作れていない。今回の関数は生成した配列を print するだけで yield してくれないのだ。

って、何の動機もなく突然こんなの書きだすわけない。これはとあるプログラミング問題のために作ったのだよ。実はそっちのほうで重複順列を使いたかったんだけれど、 yield されたらむしろ困る感じだったのだ。だから自作が必要だったわけ。そっちもまた後日載せよう。