2
$\begingroup$

Given the following lists:

v1 = {a, c, e};

v2 = {b, d, f};

how does one efficiently create the following "combination lists"?

{a, c, e};
{a, c, f};
{a, d, e};
{a, d, f};
{b, c, e};
{b, c, f};
{b, d, e};
{b, d, f};

How can one generalize the algorithm to lists v1 and v2 of arbitrary but equal length $n$?

$\endgroup$
  • 6
    $\begingroup$ Tuples[Transpose@{v1,v2}] should do it. That will also generalize to any length for v1,v2. Assuming the lengths of v1 v2 are the same. $\endgroup$ – N.J.Evans Sep 22 '15 at 19:49
  • 2
    $\begingroup$ I am speechless, really. Perfect answer! I erect a statue of you! Thanks a lot. =) $\endgroup$ – TeM Sep 22 '15 at 19:55
  • 2
    $\begingroup$ Congratulations on your first Statue Badge, @N.J.Evans! $\endgroup$ – march Sep 22 '15 at 20:26
7
$\begingroup$

I figured I should make this an answer so it can be closed.

What you're looking for is all combinations of three elements such that the first element is either {a,b}, the second element is either {c,d}, and the last element is either {e,f}. Where the choices for each element come from two given vectors v1={a,c,e}, and v2={b,d,f}. This is what Tuples is meant to do.

In order to get the answer you're after you need to manipulate the vectors a bit.

Using Transpose@{v1,v2} gives a list {{a,b},{c,d},{e,f}}. Passed to Tuples in this form, the function will create all possible combinations of the three sublists. This is the second form given in the documentation.

So the answer is simply,

Tuples[Transpose@{v1,v2}]

This can also be generalized to any number of vectors of any length, as long as the vectors have the same length. Tuples[Transpose@{v1,v2,v3}].


The only problem with vectors of different lengths is the Transpose operation. So with some assumptions about the vectors, vectors with different lengths can be handled using a trick from @The Toad for transposing uneven lists, Transpose uneven lists.

Tuples[{v1,v2,vSmaller}~Flatten~{2}]

For instance:

v1 = {1,2,3};
v2 = {6,7};
Tuples[{v1,v2}~Flatten~{2}]

Gives:

{{1, 2, 3}, {1, 7, 3}, {6, 2, 3}, {6, 7, 3}}
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.