6
$\begingroup$

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}

$\endgroup$
1
  • 4
    $\begingroup$ Variables[Level[list, {-1}]] $\endgroup$
    – Bob Hanlon
    Jan 4, 2023 at 23:12

4 Answers 4

5
$\begingroup$

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)

Reduce`FreeVariables

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 Reduce`FreeVariables:

Reduce`FreeVariables@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 Reduce`FreeVariables, and point out (among other things) that this function can take an optional second argument.

Compare

Reduce`FreeVariables[x + Log[y]]
Reduce`FreeVariables[x + Log[y],"Algebraic"]

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

Integrate`getAllVariables

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

Integrate`getAllVariables[Cos[t x] E^y, {}]

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

Cross-References

  1. Extracting variables from an expression

  2. Get all variables in an expression with Variables[] [duplicate]

  3. What does Reduce`FreeVariables really do? And can we rely on it?

$\endgroup$
1
  • 2
    $\begingroup$ (+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 :-) $\endgroup$
    – bmf
    Jan 5, 2023 at 9:20
7
$\begingroup$

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

First suggestion

Reduce`FreeVariables[list]

Second suggestion

Integrate`getAllVariables[list, {}]

The above return

list

Another way

Cases[list, _Symbol, Infinity]

Yet another one

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

The above give

list2

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

list

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

Union@getAllVariables[list]

returns

list

$\endgroup$
6
$\begingroup$

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.

$\endgroup$
4
$\begingroup$

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

Your Answer

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

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