Search code examples
wolfram-mathematicasymbolic-math

Getting all the leaves from an expression


I would like to get a List (ideally a set -- discarding repetition -- but assuming there's no direct way to do this I'll just use Union) of the leaves from a given expression.

For example, the expression

ArcTan[(-1 + 2*x)/Sqrt[3]]/Sqrt[3]

has a LeafCount of 18:

  • -1 (3)
  • 2 (3)
  • 3 (2)
  • x
  • ArcTan
  • Plus
  • Power (2)
  • Rational (2)
  • Times (3)

so I would like something like

{-1, 2, 3, x, ArcTan, Plus, Power, Rational, Times}

Actually, I really just want the functions so

{ArcTan, Plus, Power, Rational, Times}

would be ideal -- but presumably there's some not-too-difficult way to filter these when I have them.

I've had some luck with

H[s_] := If[LeafCount[s] == 1, s, Head[s]]
H /@ Level[expr, 1, Heads -> True]
H /@ Level[expr, 2, Heads -> True]
(* ... *)

but I feel like there must be a better way.


Solution

  • Your own solution does not seem bad:

    expr = ArcTan[(-1 + 2*x)/Sqrt[3]]/Sqrt[3];
    
    H[s_] := If[LeafCount[s] == 1, s, Head[s]]
    
    H /@ Level[exp, -1, Heads -> True] // Union
    
    {-1, 2, 3, ArcTan, Plus, Power, Rational, Times, x}

    Brett Champion's method is more streamlined, but I would change it a little:

    Union@Cases[expr, h_[___] :> h, {0, -1}]
    

    This way you pick up a top level head, such as ArcTan in:

    expr = ArcTan[(-1 + 2*x)/Sqrt[3]];