What is the identity for Tuples?

My question is, what list p in the following statement returns the list q?

Tuples[{{p},{q}}]


If we think of Tuples as a binary operator then p would be the identity for Tuples.

I thought an empty list would work, but evaluating the following

Tuples[{{},{1,2,3}}]


The following doesn't work either:

Tuples[{{\[EmptySet]},{1,2,3}}]


Certainly, I could write a function like the following

altTuples[p_List,q_List]:= If[Length[p]==0,q,Tuples[{p,q}]


That does exactly what I want, but I want to know if I'm missing something. Is there in fact an identity for Tuples? Is there a way to do what I want with Outer? I've tried the obvious solutions with no luck.

• How do you want your altTuples[] to behave when the length of $p$ is not zero? For example altTuples[{a, b, c}, {d, e, f}] returns Tuples[{a, b, c}, {d, e, f}], probably not what you want. – mjw Jul 8 '19 at 1:19
• I corrected altTuples. Actually I want it to return Tuples[{{a, b, c}, {d, e, f}}]. I think Nothing is what I was looking for. – JAS Jul 8 '19 at 23:27
• What you have above is almost correct (up to a typo). Anyway seems to produce what you want. 'AltTuples[{p,q}] gives the same output as Tuples[p,q] when the first argument is a list with non-zero length. – mjw Jul 8 '19 at 23:36

If {{1},{2},{3}} is fine, you can use Nothing:

Tuples[{Nothing, {1, 2, 3}}]
(* {{1}, {2}, {3}} *)


If you want {1,2,3}, you can Flatten the result, of course.

• Thank you, this does exactly what I need. – JAS Jul 8 '19 at 23:20

You can use Inactive[Sequence][] as identity like this:

Tuples[{{Inactive[Sequence][]},{q}}]//Activate


{{q}}

Use TagSetDelayed to define a function that behaves as desired:

ClearAll[iDentity]
iDentity /: {iDentity[___], a : {__}} := iDentity[a]
iDentity /: Tuples[iDentity[a_]] := a

Tuples[{iDentity[], {q}}]


{q}

Tuples[{iDentity[blah], {1, 2, 3}}]


{1, 2, 3}

Alternatively, define your function altTuples with two signatures:

ClearAll[altTuples]
altTuples[{tuplesIdentity | {} | Nothing, a_List}] := a
altTuples[x_] := Tuples[x]

altTuples[{{x, y}, {1, 2}}]


{{x, 1}, {x, 2}, {y, 1}, {y, 2}}

altTuples[{tuplesIdentity, {1, 2}}]


{1, 2}

altTuples[{{}, {1, 2}}]


{1, 2}

I think this is what you want:

altTuples[p_List, q_List] := If[Length[p] == 0, q, Tuples[{p, q}]]


The statement

altTuples[{}, {d, e, f}]


returns

{d, e, f}


and

altTuples[{a, b, c}, {d, e, f}]


returns

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