Extracting coefficients from sum

I'm having the hardest time working if I have a sum of products, with coefficients out the front, like

expr = 1 + 2 a[0] b[1] + 2 a[0] b[1] c[3] + c[6] + 5 d[3, 4]


How do I get a list of terms with their coefficients, like

{ {1, 1}, {2, a[0] b[1]}, {2, a[0] b[1] c[3]}, {1, c[6]}, {5, d[3,4]} }?


or even

{ {1, 1}, {2, {a[0], b[1]}}, {2, {a[0],b[1],c[3]} }, {1, c[6]}, {5, d[3,4]}}?


I've tried:

Table[{Coefficient[expr, i], i}, {i, Variables[expr]}]

(* {{2 b[1] + 2 b[1] c[3], a[0]}, {2 a[0] + 2 a[0] c[3], b[1]}, {2 a[0] b[1], c[3]}, {1, c[6]}, {5, d[3, 4]}}  *)


But this returns coefficients for the "individual" variables a[0], b[1], c[1], c[3], d[3,4], not the variables as they are grouped in the sum.

I also tried manually picking through the sum, without much success

{expr[[2,1]], expr[[2,2;;-1]]} (* want {2, a[0] b[1]} *)

(* {2, a[0],b[1] } *) (* YAY! *)

{expr[[4,1]], expr[[4,2;;-1]]} (* want {1, c[6]} *)

(* {6, c[]} *) (* Oh no... *)


2 Answers

You can use a combination of MonomialList and FactorTermsList. MonomialList gives a list of the monomials (including coefficients) and FactorTermsList gives a 2 element list with the overall numerical factor and the rest of the monomial:

expr = 1 + 2 a[0] b[1] + 2 a[0] b[1] c[3] + c[6] + 5 d[3, 4];

FactorTermsList /@ MonomialList[expr]


{{2, a[0] b[1] c[3]}, {2, a[0] b[1]}, {1, c[6]}, {5, d[3, 4]}, {1, 1}}

• FactorTermsList does not seem to work when the coefficients are floating numbers. For example: FactorTermsList[1.1 x^2] Apr 18 at 14:33

Update: In version 9, there is SystemReduceUtilsDumpMonomialCoefficients which (when Transposed) gives the desired result.

Transpose @ SystemReduceUtilsDumpMonomialCoefficients @ expr


{{1, 1}, {2, a[0] b[1]}, {2, a[0] b[1] c[3]}, {1, c[6]}, {5, d[3, 4]}}

It seems that this function is no longer available in version 11. The following implementation is a variation of the code behind SystemReduceUtilsDumpMonomialCoefficients:

ClearAll[coefList]
coefList[a_Times] := Select[a, #] & /@ {NumericQ, Not@*NumericQ}
coefList[a_Plus] := coefList/@(List @@ a)
coefList[a_] := {1, a}

coefList @ expr


{{1, 1}, {2, a[0] b[1]}, {2, a[0] b[1] c[3]}, {1, c[6]}, {5, d[3, 4]}}

Original answer:

Using Replace:

Replace[List @@ expr, c_.  t__ :> {c, 1 t}, 1]


{{1, 1}, {2, a[0] b[1]}, {2, a[0] b[1] c[3]}, {1, c[6]}, {5, d[3, 4]}}

Replace[List @@ expr, c_.  t__ :> {c, {t}}, 1]


{{1, {1}}, {2, {a[0], b[1]}}, {2, {a[0], b[1], c[3]}}, {1, {c[6]}}, {5, {d[3, 4]}}}

If you wish you can Flatten the first sublist:

FlattenAt[%, {{1, 2}}]


{{1, 1}, {2, {a[0], b[1]}}, {2, {a[0], b[1], c[3]}}, {1, {c[6]}}, {5, {d[3, 4]}}}