私が考えることができるデカルト積の最も単純な再帰的定義は次のようになります。あなたと同じように、これにはループがあります。実際には、リスト内包表記に 2 つのループが埋め込まれています。あなたのものとは異なり、これは 2 つ以上のシーケンスを処理できます。
def product(*seqs):
if not seqs:
return [[]]
else:
return [[x] + p for x in seqs[0] for p in product(*seqs[1:])]
これがどのように機能するかを理解するためのウォークスルーです。定義により、空のシーケンスのデカルト積 ( product()
) は、空のシーケンスを含むシーケンスです。つまり、product()
== [[]]
--理由についてはこちらを参照してください。
product([1, 2, 3])
--seqs
が空ではないので、戻り値はリスト内包表記の結果であるとしましょう。この場合、product(*seqs[1:])
== product(*[])
== product()
==[[]]
であるため、リスト内包表記は次と同等です。
[[x] + p for x in seqs[0] for p in [[]] ]
これはこれらすべてと同等です:
[[x] + [] for x in seqs[0]]
[[x] for x in seqs[0]]
[[1], [2], [3]]
別のシーケンスを追加すると、 が得られproduct([4, 5, 6], [1, 2, 3])
ます。リスト内包表記は次のようになります。
[[x] + p for x in [4, 5, 6] for p in product(*seqs[1:])]
[[x] + p for x in [4, 5, 6] for p in [[1], [2], [3]]]
[[4, 1], [4, 2], [4, 3], [5, 1], [5, 2], [5, 3], [6, 1], [6, 2], [6, 3]]
そこからパターンが続きます。追加のシーケンスごとに、シーケンス内の各値が、次のシーケンスのデカルト積内の各値の前に追加されます。