# Simplify the code

I have a function that grabs the second part of the list and change it to times,

mylist = {{{y1, y2, y3}, {y3, y4, y5}}, {{w1, w2, w3}, {w4, w5, w6}}};
g[x_] := x /. List -> Times
Map[g, mylist, {2}]


I wrote it above, but I think I should be able to make it much simpler code using @ # and &. Any suggestion?

• FWIW: you don't need to define g: you can use /. as an operator directly: Map[ReplaceAll[List -> Times], mylist, {2}], or even Map[# /. List -> Times &, mylist, {2}]. – AccidentalFourierTransform Jun 30 '19 at 1:42
• Idiomatic way is to use: Apply[Times, mylist, {2}]. It is short and easy to understand. – Shadowray Jul 1 '19 at 22:17

Since you appear to want to multiply the list only when all of its elements are atomic, how about just

mylist /. {s__?AtomQ} :> Times[s]


It appears to be the most direct translation of your thought.

☺lookMaNoLetters☺ = 1 ## & @@@ # & /@ # &;

☺lookMaNoLetters☺ @ mylist


{{y1 y2 y3, y3 y4 y5}, {w1 w2 w3, w4 w5 w6}}

Further variations:

☺lookMaNoLettersOrNumbers☺ = # ##2 & @@@ # & /@ # &;
☺ApplyTimesAtLevel2☺ = # ##2 & @@ ## &[#, {2}] &;
☺InCaseYouLikeInfix☺ = # ~ (# ##2 & @@ ## &) ~ {2} &;
☺IfYouLikeVerbose☺ = Map[Map @ Apply @ Times]


You can use as many @s as you like:

☺♬♪♫♪☺ = ## & @@@ (## & @@@ ## & @@@ 1 ## & @@@ {##} & @@@ {##} & /@ #) &;

☺♬♪♫♪☺ @ mylist


{{y1 y2 y3, y3 y4 y5}, {w1 w2 w3, w4 w5 w6}}

• I'd add a disclaimer suggesting OP should not actually code this way... – lirtosiast Jul 1 '19 at 3:39
• What a fun answer! I already accept the answer, but it is amazing, and very helpful for me to understand the language. Thanks – Saesun Kim Jul 1 '19 at 7:23
Times @@@ # & /@ mylist
(*    {{y1 y2 y3, y3 y4 y5}, {w1 w2 w3, w4 w5 w6}}    *)

• This seems less clear and less general than Apply[Times, mylist, {2}] or ...{-2}. – lirtosiast Jun 29 '19 at 16:39
• @lirtosiast oh yes for sure, but the OP was specifically asking for @ # & gobbledygook :-) Ideally there would be a @@@@ operator for this purpose. – Roman Jun 29 '19 at 16:48
• Thank you so much for the clear and nice answer! – Saesun Kim Jun 29 '19 at 16:59

Another way to view your function is as a generalized inner product:

Inner[Times, mylist, {1, 1, 1}, Times]
{{y1 y2 y3, y3 y4 y5}, {w1 w2 w3, w4 w5 w6}}

Map[Times[Sequence @@ #] &] /@ mylist
(* {{y1 y2 y3, y3 y4 y5}, {w1 w2 w3, w4 w5 w6}} *)


Apply can be used with level specificator in the same way as Map:

Apply[Times, mylist, {2}]


{{y1 y2 y3, y3 y4 y5}, {w1 w2 w3, w4 w5 w6}}

If mylist is a depth-three rectangular array, the following will work; if it is also packed, this will minimally unpack and produce a packed array:

Times @@ Transpose[mylist, {2, 3, 1}]
(*  {{y1 y2 y3, y3 y4 y5}, {w1 w2 w3, w4 w5 w6}}  *)


More obfuscatory fun:

Block[{★},
★ /: {x__★} := Block[{★ = # &}, 1 x];
Function[s, ★@s, Listable]@mylist
]
(*  {{y1 y2 y3, y3 y4 y5}, {w1 w2 w3, w4 w5 w6}}  *)

• You could also compile for no unpacking (_Real or _Integer, but in separate functions): cf = Compile[{{a, _Real, 3}}, Times @@ Transpose[a, {2, 3, 1}]]; cf@myarray. Or force Apply to compile with SetSystemOptions["CompileOptions" -> "ApplyCompileLength" -> 0];. – Michael E2 Jul 1 '19 at 4:28

Been a while since I coded in Wolfram...

Times @@ mylist[[2]]


So long that I had to look up indexing.

• Almost forgot that Mathematica had a nifty set of ways to specify indexing. Ones that I tried to copy. – kozner Jun 30 '19 at 9:04
• This produces {w1 w4, w2 w5, w3 w6}, which is not close to what is sought. (It's good site practice to include the output of your code, when it's not too long.) Makes you wonder about the upvote, though, doesn't it. – Michael E2 Jul 1 '19 at 3:58