10
$\begingroup$

Why do I get this error message? It seems to me that the level specification should have done the job.

In[1]:= RandomInteger[10, {10, 2}]
In[2]:= Position[%, _?(#[[1]] > 5 &), {1}] 

Out[1]:= {{0, 0}, {1, 7}, {3, 0}, {5, 5}, {1, 5}, {10, 6}, {3, 9}, \
{0, 1}, {9, 1}, {2, 0}}

During evaluation of In[2]:= Part::partd: Part specification List[[1]] is longer than depth of object. >>

Out[2]:= {{6}, {9}}
$\endgroup$
6
  • $\begingroup$ Position[list, _, {-2}] and Position[list, _, {1}] are different $\endgroup$
    – garej
    Commented Jan 26, 2016 at 16:37
  • 1
    $\begingroup$ @garej why different? $\endgroup$
    – Al Guy
    Commented Jan 26, 2016 at 23:25
  • $\begingroup$ you may find this famous post useful. $\endgroup$
    – garej
    Commented Jan 27, 2016 at 9:18
  • $\begingroup$ Also this form works Position[%, _?(And[Depth[#] > 1, #[[1]] > 5] &), {1}] $\endgroup$
    – garej
    Commented Jan 27, 2016 at 13:59
  • 1
    $\begingroup$ @garej I think you will find interest in my answer to the original question now linked at the top. You do not need Depth etc., but only Position[%, _[__]?(#[[1]] > 5 &), {1}]. If one is willing to modify the test function itself this can be written more cleanly as Position[%, _[x_, ___] /; x > 5, {1}]. $\endgroup$
    – Mr.Wizard
    Commented Jan 29, 2016 at 7:41

2 Answers 2

12
$\begingroup$

The documentation for Position provides the answer:

The default level specification for Position is {0,Infinity}, with Heads->True.

You're not setting Heads -> False, so Position will look at:

Level[{{8, 7}, {10, 8}, {6, 10}, {3, 2}, {9, 8}, {0, 1}, {2, 1},
{1, 10}, {6, 8}, {5, 9}}, 1, Heads -> True]

Which is:

{List, {8, 7}, {10, 8}, {6, 10}, {3, 2}, {9, 8}, {0, 1}, {2, 1}, {1, 10}, {6, 8}, {5, 9}}

You're then asking Position to take #[[1]], i.e. List[[1]]... Error!

This works:

RandomInteger[10, {10, 2}]
Position[%, _?(#[[1]] > 5 &), {1}, Heads -> False]
$\endgroup$
3
$\begingroup$

I think there are two more lines from Position documentation might be relevant for the OP.

A positive level n consists of all parts of expr specified by n indices.

A negative level -n consists of all parts of expr with depth n.

So, for the OP task this code works even with default Heads->True:

list = RandomInteger[10, {10, 2}];

Position[list, _?(#[[1]] > 5 &), {-2}]

To see why it happens let's make a toy list, ls = {{a,b},{c,d}}.

Position[ls, _, {1}]
(*  {{0}, {1}, {2}}  *)

We may see, that all positions have one index inside {}. Heads included (they have 0 as one of indeces).

Position[ls, _, {2}]
(*  {{1, 0}, {1, 1}, {1, 2}, {2, 0}, {2, 1}, {2, 2}}  *)

We may see, that all positions have two indeces inside {}. Heads included.


On the contrary, negative levelspecs work in a different way in Position:

 Position[ls, _, {-2}]
 (* {{1}, {2}} *)

These are positions of elements with Depth[..]==2; let's check this:

 MapAt[Depth[#] &, ls, Position[ls, _, {-2}]]
 (*  {2, 2} *)

As a footnote, this statement gives different result (note the head 1):

 MapAt[Depth[#] &, ls, Position[ls, _, {1}]]
 (*  1[2,2] *)

Finally,

 Position[ls, _, {-1}]
 (* {{0}, {1, 0}, {1, 1}, {1, 2}, {2, 0}, {2, 1}, {2, 2}} *)

These are positions of elements with Depth[..]==1; let's check:

MapAt[Depth[#] &, ls, Position[ls, _, {-1}]]
(* 1[1[1, 1], 1[1, 1]] *)

We may see all 1 (including Heads).


One has to be careful with more complex cases of nested lists.

$\endgroup$

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