Levels in Expressions

The (RefLink[Part, paclet:ref/Part]) function allows you to access specific parts of Wolfram Language expressions. But particularly when your expressions have fairly uniform structure, it is often convenient to be able to refer to a whole collection of parts at the same time.

Levels provide a general way of specifying collections of parts in Wolfram Language expressions. Many Wolfram Language functions allow you to specify the levels in an expression on which they should act.

Here is a simple expression, displayed in tree form:

(t={x,{x,y},y})//TreeForm

This searches for x in the expression t down to level 1. It finds only one occurrence:

Position[t,x,1]

This searches down to level 2. Now it finds both occurrences of x:

Position[t,x,2]

This searches only at level 2. It finds just one occurrence of x:

Position[t,x,{2}]

Controlling (RefLink[Position, paclet:ref/Position]) using levels.

You can think of levels in expressions in terms of trees. The level of a particular part in an expression is simply the distance down the tree at which that part appears, with the top of the tree considered as level 0.

It is equivalent to say that the parts which appear at level n are those that can be specified by a sequence of exactly n indices.

Level specifications.

Here is an expression, displayed in tree form:

(u=f[f[g[a],a],a,h[a],f])//TreeForm

This searches for a at levels from 2 downward:

Position[u,a,{2,Infinity}]

This shows where f appears other than in the head of an expression:

Position[u,f,Heads->False]

This includes occurrences of f in heads of expressions:

Position[u,f,Heads->True]

Testing and extracting levels.

This gives a list of all parts of u that occur down to level 2:

Level[u,2]

Here are the parts specifically at level 2:

Level[u,{2}]

When you have got the hang of ordinary levels, you can try thinking about negative levels. Negative levels label parts of expressions starting at the bottom of the tree. Level -1 contains all the leaves of the tree: objects like symbols and numbers.

This shows the parts of u at level -1:

Level[u,{-1}]

You can think of expressions as having a "depth", as shown by (RefLink[TreeForm, paclet:ref/TreeForm]). In general, level -n in an expression is defined to consist of all subexpressions whose depth is n.

The depth of g[a] is 2:

Depth[g[a]]

The parts of u at level -2 are those that have depth exactly 2:

Level[u,{-2}]