5
$\begingroup$

I want to transform expressions into lists of elements. For example,

b*c + a*b*c /. Plus -> List /. Times -> List

{{b, c}, {a, b, c}}

However, when the expression contains other functions such as

a*b*c + Cos[x - y] /. Plus -> List /. Times -> List

I get

{{a, b, c}, {Cos[x], Cos[y]}}

I want to protect the arguments inside of functions. In the above example, I want to get

{{a, b, c}, {Cos[x - y]}}

Any tips for me?

$\endgroup$
7
$\begingroup$

In this example, I am assuming that the structure of your expressions will always be similar to your input:

input = a*b*c + Cos[x - y];

The method below is not exactly general.

First remove the outer-most Plus:

list = List @@ Expand[input]
(* {a b c, Cos[x - y]} *)

We then Map Apply over the list while being careful to avoid those expressions which are monomials:

If[Head@# === Times, List @@ #, {#}] & /@ list
(*  {{a, b, c}, {Cos[x - y]}} *)

Some explanations

For the purposes of making this answer actually more useful, I'll comment here about why the OP's method fails. Let's take it in steps.

First of all, x - y is interpreted as x + (-1)*y:

x - y // Fullform
(* Plus[x,Times[-1,y]] *)

and therefore the first replacement fails right off the bat, because this Plus gets replaced, too. Now,

Cos[x - y] /. Plus -> List
(* {Cos[x], Cos[y]} *)

This might seem strange, but it is a consequence of Cos being Listable:

Attributes @ Cos
(* {Listable, NumericFunction, Protected} *)

which means that it automatically Threads over lists. In other words

Cos[x - y] /. Plus -> List

first becomes Cos[{x, -y}] which then becomes {Cos[x], Cos[-y]} which then automatically gets simplified to {Cos[x], Cos[y]}. To see this happen in action:

Cos[x - y] /. Plus -> List // Trace

enter image description here

Similar kinds of things can happen with replacements like Times -> <head>, so in general, I would recommend getting around this in other ways.

My solution was to use Apply instead of ReplaceAll. Apply can also be thought of as ReplaceHead:

Apply[f, g[x]]
(* f[x] *)

It's cleaner in this case, because the OP is interested only in replacing Heads of the expressions.

$\endgroup$
  • $\begingroup$ your definition of "input" seems to be wrong $\endgroup$ – eldo Oct 29 '15 at 18:07
  • $\begingroup$ @eldo. Right you are! Fixed. $\endgroup$ – march Oct 29 '15 at 19:02
2
$\begingroup$

This seems to admit a simple recursive approach.

terms[(Times | Plus)[args__]] := terms /@ {args}
terms[x_] := x

Then

terms[b c + a b c]

{{b, c}, {a, b, c}}

terms[a b c + Sin[x] Cos[x - y]]

{{a, b, c}, {Cos[x - y], Sin[x]}}

However,

terms[d/e Cos[x - y]]

{d, 1/e, Cos[x - y]}

Will this last result will be acceptable? I can not make out from the question what is expected in this case.

$\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.