Command Position always comes with two extra curly brackets {{}} when it's just one index for the location. I use [[1,1]] in front of my position commands. Is there a better way?

  • 2
    $\begingroup$ Why is using [[1,1]] not acceptable? The reason Position does this is because in general, there can be more than one position where the element is matched and the position itself might be a list (e.g. in a multi-dimensional array). $\endgroup$ – rm -rf Feb 26 '14 at 20:04
  • 4
    $\begingroup$ "Position returns a list of positions in a form suitable for use in Extract, ReplacePart, and MapAt." $\endgroup$ – Dr. belisarius Feb 26 '14 at 20:08
  • 1
    $\begingroup$ I think [[1,1]] is the best thing you can do. Moreover, [[1,1]] indicates that it will be an advantage adding 3rd and 4th argument: Position[expr,val,Automatic,1] if you didn't already do that... $\endgroup$ – Coolwater Feb 26 '14 at 20:10
  • $\begingroup$ an alternative is First@First@Position cant say better, just a matter of taste $\endgroup$ – george2079 Feb 26 '14 at 20:34

No, to my knowledge there isn't a better way, but there is a good reason for this behaviour.

First, the element might appear more than once, so Position must return a list:

Position[{1, 2, 1, 3}, 1]

(* ==> {{1}, {3}} *)

Second, you might be searching a more complicated compound expression than a list, e.g. a matrix, so each list element might need to hold more than one index:

Position[{{1, 2, 1, 3}, {4, 5, 1, 6}}, 1]

(* ==> {{1, 1}, {1, 3}, {2, 3}} *)

Position[{1, {2, 1}}, 1]

(* ==> {{1}, {2, 2}} *)

Each index set that Position returns can be directly used in the Extract function, which is sometimes more convenient to use with Positions's return value than Part.

You might think that it would be better if Position returned a single number as a special case when there's a single match only in a one-dimensional list, such as

Position[{1, 2, 3}, 1]

(* ==> {{1}} *)

If Position did this, programs using it would not be easily generalizable to different inputs and the user would sometimes need to handle this special case.

If you only need the first occurrence of the pattern, you might consider using the fourth argument to your advantage (as Coolwater has pointed out in a comment above):

Position[list, patt, Infinity, 1]

immediately terminates when the first match is found so it is really useful for large redundant lists. If you are only interested in matches of the topmost level, use the third argument:

Position[list, patt, 1, 1]

This is equivalent to passing a vector as list, that only has depth 1.

  • $\begingroup$ I gladly remove my answer, but would you mind if I edit in the fourth argument for Position as a shortcut? $\endgroup$ – István Zachar Feb 26 '14 at 20:11
  • $\begingroup$ @IstvánZachar Please do. We posted seconds apart! $\endgroup$ – Szabolcs Feb 26 '14 at 20:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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