从表达式中获取所有叶子

时间:2011-08-18 20:35:30

标签: wolfram-mathematica symbolic-math

我想得到一个List(理想情况下是一组 - 丢弃重复 - 但假设没有直接的方法可以做到这一点,我只会使用Union)来自给定的叶子表达

例如,表达式

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

LeafCount为18:

  • -1(3)
  • 2(3)
  • 3(2)
  • X
  • ARCTAN
  • 电力(2)
  • 理性(2)
  • 时代(3)

所以我想要像

这样的东西
{-1, 2, 3, x, ArcTan, Plus, Power, Rational, Times}

实际上,我真的只想要这些功能

{ArcTan, Plus, Power, Rational, Times}

会很理想 - 但是当我拥有它们时,可能会有一些不太难的方法来过滤它们。

我运气好了

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

但我觉得必须有更好的方法。

4 个答案:

答案 0 :(得分:8)

您可以使用Cases

In[176]:= 
Cases[ArcTan[(-1 + 2*x)/Sqrt[3]]/Sqrt[3], h_[___] :> h, 
  {0,Infinity}] // DeleteDuplicates

Out[176]= {Rational, Power, Times, Plus, ArcTan}

答案 1 :(得分:7)

你自己的解决方案看起来并不糟糕:

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的方法更精简,但我会稍微改变一下:

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

这样您就可以选择一个顶级头部,例如ArcTan

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

答案 2 :(得分:6)

对于原始问题,可以通过等级获得所有叶子,等级规格为{-1}并允许头部。

In[87]:= Level[ArcTan[(-1 + 2*x)/Sqrt[3]]/Sqrt[3], {-1}, Heads -> True]

Out[87]= {Times, Power, 3, -(1/2), ArcTan, Times, Power, 3, -(1/
    2), Plus, -1, Times, 2, x}

Daniel Lichtblau

答案 3 :(得分:4)

这就是我想出来的......

In[92]:= f[e_] := DeleteDuplicates[Prepend[Head[#] & /@ Level[e, Depth[e]], Head[e]]]

In[93]:= f[ArcTan[(-1 + 2*x)/Sqrt[3]]/Sqrt[3]]

Out[93]=  {Times, Integer, Rational, Power, Symbol, Plus, ArcTan}

然后,您可以轻松删除IntegerSymbol

<小时/> 编辑:

现在让我们将表达式包装在一个列表中,以确保我们获得最重要的头部。 (原始表达式以Times为首,但内部也有两次。

In[139]:= a = {ArcTan[(-1 + 2*x)/Sqrt[3]]/Sqrt[3]}
In[140]:= TreeForm[a, AspectRatio -> .7]

TreeForm

In[142]:= f[a]
Out[142]= {List, Integer, Rational, Power, Symbol, Times, Plus, ArcTan}