7
$\begingroup$

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?

$\endgroup$
2
  • 1
    $\begingroup$ 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}]. $\endgroup$ Jun 30, 2019 at 1:42
  • $\begingroup$ Idiomatic way is to use: Apply[Times, mylist, {2}]. It is short and easy to understand. $\endgroup$
    – Ray Shadow
    Jul 1, 2019 at 22:17

8 Answers 8

10
$\begingroup$

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.

$\endgroup$
16
$\begingroup$
☺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}}

$\endgroup$
2
  • 5
    $\begingroup$ I'd add a disclaimer suggesting OP should not actually code this way... $\endgroup$
    – lirtosiast
    Jul 1, 2019 at 3:39
  • 1
    $\begingroup$ What a fun answer! I already accept the answer, but it is amazing, and very helpful for me to understand the language. Thanks $\endgroup$
    – Saesun Kim
    Jul 1, 2019 at 7:23
7
$\begingroup$
Times @@@ # & /@ mylist
(*    {{y1 y2 y3, y3 y4 y5}, {w1 w2 w3, w4 w5 w6}}    *)
$\endgroup$
3
  • 6
    $\begingroup$ This seems less clear and less general than Apply[Times, mylist, {2}] or ...{-2}. $\endgroup$
    – lirtosiast
    Jun 29, 2019 at 16:39
  • 5
    $\begingroup$ @lirtosiast oh yes for sure, but the OP was specifically asking for @ # & gobbledygook :-) Ideally there would be a @@@@ operator for this purpose. $\endgroup$
    – Roman
    Jun 29, 2019 at 16:48
  • $\begingroup$ Thank you so much for the clear and nice answer! $\endgroup$
    – Saesun Kim
    Jun 29, 2019 at 16:59
5
$\begingroup$

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}}
$\endgroup$
5
$\begingroup$
Map[Times[Sequence @@ #] &] /@ mylist
(* {{y1 y2 y3, y3 y4 y5}, {w1 w2 w3, w4 w5 w6}} *)
$\endgroup$
3
$\begingroup$

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}}

$\endgroup$
3
$\begingroup$

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}}  *)
$\endgroup$
1
  • $\begingroup$ 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];. $\endgroup$
    – Michael E2
    Jul 1, 2019 at 4:28
-1
$\begingroup$

Been a while since I coded in Wolfram...

Times @@ mylist[[2]]

So long that I had to look up indexing.

$\endgroup$
2
  • $\begingroup$ Almost forgot that Mathematica had a nifty set of ways to specify indexing. Ones that I tried to copy. $\endgroup$
    – kozner
    Jun 30, 2019 at 9:04
  • 1
    $\begingroup$ 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. $\endgroup$
    – Michael E2
    Jul 1, 2019 at 3:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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