# Split expression into list of terms

I'm looking for a nice way to split an expression into a list of the terms (i.e. the addends).

The desired behavior in:

terms[a^2 + a^-2 + c]
(* Out: {a^2, a^-2, c} *)
terms[a*b*c]
(* Out: {a*b*c} *)


I've tried a few solutions. MonomialList doesn't work if the expression is not a polynomial. I've also tried

Level[a + b + c, 1]
(* Out: {a, b, c} *)


But the problem is it breaks down for monomials.

Level[a, 1]
(* Out: {} *)
Level[a*b*c, 1]
(* Out: {a, b, c} *)


The desired output would be {a} and {a b c} respectively.

• terms[a*b*c] but terms here are a and b and c. Unless you are using your own definition of what a term is. So you can use List @@ expr  to obtain the terms. expr = a^2 + a^-2 + c; List @@ expr  gives {1/a^2, a^2, c} and expr = a*b*c; List @@ expr  gives {a, b, c} etc.. Feb 15 '20 at 22:12
• @Nasser Thank you for your reply. To clarify, I am using "term" to mean addend. I am finding that the  List @@ expr  similarly does not handle monomials correctly. Namely expr = a; List @@ expr returns just a rather than {a}. Feb 15 '20 at 22:18

ClearAll[terms]
SetAttributes[terms, HoldAll]
terms[Plus[a__]] := {a}
terms[a_?AtomQ] := {a}
terms[a_] := a


Examples:

ClearAll[a, b, c, d]

terms[a]


{a}

terms[a + b + c]


{a, b, c}

terms[a b c]


a b c

terms[a^2 + a^-2 + c]


{a^2, 1/a^2, c}

terms[a b c + 3 Sin[c + d] + Log@d]


{a b c, 3 Sin[c + d], Log[d]}

• This works perfectly! I appreciate you putting in the effort. Feb 16 '20 at 2:21
• @mwalth, you are welcome. And welcome to mma.se.
– kglr
Feb 16 '20 at 2:28
• As always: cool answer from you! Feb 17 '20 at 9:52
• But when I write u=a+b and terms[u] your function does not work. Do you know how to generalize? Jun 19 '20 at 13:19
• @yarchik, you can use terms[Evaluate@u] ?
– kglr
Jun 19 '20 at 20:44

For the examples you mentioned, the following simple replacement works:

a^2 + a^-2 + c /. Plus -> List

(* Out: {1/a^2, a^2, c} *)


Note that the ordering is not retained, but then you probably shouldn't depend on the order of monomials anyway because MMA might rewrite your expression on its own to conform to its "canonical" format (e.g. evaluating b - a returns -a + b).

Similarly,

a*b*c /. Plus -> List     (* Out: a*b*c *)
a /. Plus -> List         (* Out: a     *)

• Thank you for your response! This seems to work well for expressions with multiple expressions, but I'm finding that abc /. Plus->List returns abc whereas I would hope for it to return the singleton list {abc}. Do you know how to modify so that it returns a list regardless of the number of terms in the input? Feb 16 '20 at 2:33

No sure whether I got your point, but you can do something like (o.k. broth-force attack ;-) ):

    makeList[term_] :=
ToExpression /@ StringSplit[ToString[term, InputForm], "+"
]


then

temp = a^2 + a^-2 + c


and

makeList@temp


yields:

{1/a^2, a^2, c}

• Thank you for the response. This was a route I thought about going also. I realize I didn't specify this in the question, but I also need it to split terms that have a minus "-" in addition to a plus "+". Do you know if this is possible with your method? Feb 16 '20 at 2:23
• You can use StringSplit[term,{"+","-"}] this should work Feb 16 '20 at 8:23
• Very good, thank you! Feb 16 '20 at 13:17