# Applying function to cartesian product of two lists

I have two lists

X = {1, 2, 3};
Y = {5, 6, 7, 8};


I want to apply function g[x,y_,z_] to all pairs from X*Y, so I need to get a list {g[x,1,5],g[x,1,6]…,g[x,3,8]}

I came up with this syntax

g[x, ##] &@(Sequence @@ #) & /@ Tuples[{X, Y}]


and it gives what I want.

Is there more elegant way to do it?

Update: The most elegant way is proposed by belisarius:

f[1, ##] & @@@ Tuples[{x, y}]


I compared performance of three methods

f[x_, y_, z_] := x + y + z;
bel[x_, y_] := f[1, ##] & @@@ Tuples[{x, y}];
mar[x_, y_] := Flatten[Outer[f[1, ##] &, x, y]];
bkow[x_, y_] := f[1, ##] &@(Sequence @@ #) & /@ Tuples[{x, y}];

benchmark[f_, n_] :=
Module[{l = Range[1, n]},
Mean@Table[First@AbsoluteTiming[f[l, l]], {20}]];

TableForm[
Table[benchmark[fun, n]/n/n, {fun, {bel, mar, bkow}}, {n, #}],
TableHeadings -> {{"bel", "mar", "bkow"}, #}] &@{10, 30, 100, 300,
1000}


and it looks like Outer is a bit faster, but the f[1, ##] & @@@ Tuples[{x, y}] definitely looks cleaner. Results are normalized over n^2 • Outer Jun 4, 2015 at 17:30
• Or Flatten[Outer[g[x, #1, #2] &, X, Y]]. @bills I think it needs Sequence@# in your expression? Jun 4, 2015 at 17:46
• g[x, ##] & @@@ Tuples[{X, Y}] Jun 4, 2015 at 18:10
• Actually, @march's use of Outer[] can be simplified: Outer[g[x, ##] &, X, Y] // Flatten. Jun 5, 2015 at 3:41
• @J. M. SlotSequence. One of many things that could revolutionize my life. Jun 5, 2015 at 3:55

As requested, I'm copying the above comment as an answer:

g[x, ##] & @@@ Tuples[{X, Y}]


seems an elegant way to me

• I'd like to add to this answer that Outer has the advantage over g[x, ##] & @@@ Tuples[{X, Y}] when it comes to packed arrays, since Outer doesn't unpack while @@@ does. Feb 8, 2018 at 10:45
Distribute[g[x, X, Y], List]


{g[x, 1, 5], g[x, 1, 6], g[x, 1, 7], g[x, 1, 8],
g[x, 2, 5], g[x, 2, 6], g[x, 2, 7], g[x, 2, 8],
g[x, 3, 5], g[x, 3, 6], g[x, 3, 7], g[x, 3, 8]}