# Obtaining non numerical elements from list containing equations

Suppose we have the following list:

list= {a,3b + c - d,x1 - 4y,g + l,x2 + z}

Is there a way to obtain a list of the non-numerical elements present here?

The output should be a list

{a,b,c,d,x1,y,g,l,x2,z}

• Variables[Level[list, {-1}]] Commented Jan 4, 2023 at 23:12

As @bmf has stated, the comments on this question suggesting the use of Variables should be turned into an answer.

I have collated the comments (one of them my own), and marked this answer 'Community Wiki': feel free to edit.

Variables

list={a,3b + c - d,x1 - 4y,g + l,x2 + z}
Variables@list

(* {a, b, c, d, g, l, x1, x2, y, z} *)


@Bob Hanlon has suggest the following neat modification:

Variables[Level[list, {-1}]]


(I now see that this was also suggested by @Basheer Algohi in 2004)

ReduceFreeVariables

In addition, both J. M.'s persistent exhaustion (see here), and Carl Woll in a comment (and others), have drawn attention to the (apparently) undocumented function ReduceFreeVariables:

ReduceFreeVariables@list

(* {a, b, c, d, g, l, x1, x2, y, z} *)


Both Michael E2 and rogerl have posted in-depth answers (see here and here on ReduceFreeVariables, and point out (among other things) that this function can take an optional second argument.

Compare

ReduceFreeVariables[x + Log[y]]
ReduceFreeVariables[x + Log[y],"Algebraic"]

(* {x, y} *)
(* {x, Log[y]} *)


IntegrategetAllVariables

Another undocumented function, which Michael E2 has suggested in an answer to another question, is IntegrategetAllVariables (and using his example):

IntegrategetAllVariables[Cos[t x] E^y, {}]

((*  {t, x, y}  *)


Cross-References

• (+1) Many thanks for doing that. I honestly think that these approaches are the best and most straightforward and if it were up to me, I would accept one of those as the proper answer to the question. The other alternatives are fun, educational, etc etc :-)
– bmf
Commented Jan 5, 2023 at 9:20

In my opinion, the comments by @Bob Hanlon and @user1066 are the best approaches. Perhaps turn the comments into answers(?)

First suggestion

ReduceFreeVariables[list]


Second suggestion

IntegrategetAllVariables[list, {}]


The above return

Another way

Cases[list, _Symbol, Infinity]


Yet another one

Cases[list, Except[_?NumericQ, _Symbol], Infinity]


The above give

Edit 1: with the use of Union you can arrange the list to be exactly the same as in the first two cases. So, the above can become

Union@Cases[list, _Symbol, Infinity]


and

Union@Cases[list, Except[_?NumericQ, _Symbol], Infinity]


which yield

Edit 2: we can use the very impressive code developed by Daniel Lichtblau on stackoverflow.

Union@getAllVariables[list]


returns

Only a little shorter than Giovanni's:
Edit: (But not as shot as bmf, user1066, and Bob Hanlon)

Select[DeleteDuplicates@Flatten@Apply[List, list, Infinity], ! NumberQ[#] &]


{a, b, c, d, x1, y, g, l, x2, z}

It replaces the heads at all levels with List then Flatten all the lists and then selects the non-numbers.

I have come up with an answer that works.

list = {a, 3 b + c - d, x1 - 4 y, g + l, x2 + z}

list = Flatten[StringSplit[ToString[#] & /@ Flatten[list],{"-", "+", " "}]]

elements =  DeleteCases[Cases[ToExpression[#] & /@ list, _?(! NumberQ[#] &)], Null]


The output is the following, which is what we wanted:

{a, 3 b + c - d, x1 - 4 y, g + l, x2 + z}

{"a", "3", "b", "", "", "c", "", "", "d", "x1", "", "", "4", "y", \
"g", "", "", "l", "x2", "", "", "z"}

{a, b, c, d, x1, y, g, l, x2, z}

list = {a, 3 b + c - d, x1 - 4 y, g + l, x2 + z};


Using Extract

p = Position[list, _Symbol, Heads -> False]


{{1}, {2, 1, 2}, {2, 2}, {2, 3, 2}, {3, 1}, {3, 2, 2}, {4, 1}, {4, 2}, {5, 1}, {5, 2}}

Extract[list, p]


{a, b, c, d, x1, y, g, l, x2, z}

This returns the variables as they appear, Variables sorts them:

Variables @ list
`

{a, b, c, d, g, l, x1, x2, y, z}