# Understanding PatternTest inside Position

I have a list of n dimensional vectors (n=3 in this example). I want to find the position of all vectors for which all elements other than the $i^{th}$ element are equal to some value (2 in this example) and the value of the $i^{th}$ element is not restricted. I've been using the following approach: Create a pattern test that, when applied to a vector (i) deletes the ith element, (ii) deletes duplicates from the remaining elements, and (iii) checks whether the remaining list of non-duplicates is equal to {2}.

points = {{0, 1, 2}, {2, 4, 2}, {2, 1, 2}, {2, 3, 4}};
Position[points, _?(DeleteDuplicates[Delete[#, 2]] == {2} &),{1}]


This approach works, but in the process I see several of the following messages:

Part 2 of List does not exist

Just to make sure my pattern test function is working, I tried

(DeleteDuplicates[Delete[#, 2]] == {2} &) /@ points
(*{False, True, True, False}*)


The messages go away if I change my pattern test by including List immediately after the underscore:

Position[points, _List?(DeleteDuplicates[Delete[#, 2]] == {2} &),{1}]


As I am already providing a level specification, why is the _List necessary to avoid these messages? What is happening when _List is not included?

It's because Position looks at Heads as well by default:

points = {{0, 1, 2}, {2, 4, 2}, {2, 1, 2}, {2, 3, 4}};
Position[points, _?(DeleteDuplicates[Delete[#, 2]] == {2} &),{1}, Heads->False]


{{2}, {3}}

You could debug this by using TracePrint:

TracePrint[
Position[points, _?(DeleteDuplicates[Delete[#,2]]=={2}&), {1}],
_DeleteDuplicates
]


DeleteDuplicates[Delete[List,2]]

Delete::partw: Part 2 of List does not exist.

Delete::partw: Part 2 of List does not exist.

DeleteDuplicates[Delete[{0,1,2},2]]

DeleteDuplicates[{0,2}]

DeleteDuplicates[Delete[{2,4,2},2]]

DeleteDuplicates[{2,2}]

DeleteDuplicates[Delete[{2,1,2},2]]

DeleteDuplicates[{2,2}]

DeleteDuplicates[Delete[{2,3,4},2]]

DeleteDuplicates[{2,4}]

{{2}, {3}}

Notice the DeleteDuplicates[Delete[List,2]] output.

• And there it is, in the "details and options" of the documentation. Apologies for missing that before posting. Thanks for explaining. Commented Aug 9, 2017 at 17:30
points = {{0, 1, 2}, {2, 4, 2}, {2, 1, 2}, {2, 3, 4}};
check[list_] := DeleteDuplicates[Delete[list, 2]] == {2};
Position[points,Except[List, _?check], {1}]

(* {{2}, {3}} *)

Position[points, {a_, _, a_}]


{{2}, {3}}

• Could this approach be easily extended so that it could take, as an argument, the position of the element one wants to ignore? For example, it would generate {_,a_,a_} for argument value 1 and {a_,a_,_} for argument value 3? Commented Aug 9, 2017 at 19:25
• @eldo i realized we can use OrderlessPatternSequence in your approach to make it generic i.e. Position[points, {OrderlessPatternSequence[a_, _, a_]}] Commented Aug 9, 2017 at 19:25
• You can extend it to fpos[list_, pos_] := Position[list, Insert[{a_, a_}, Blank[], pos]]
– eldo
Commented Aug 9, 2017 at 19:40
• @AliHashmi In my case I do care about the order, I just want to use every order separately. Your example led me to discover Sort[Permutations[{a_,_,a_}]], which would do the job. Thanks. Commented Aug 9, 2017 at 19:41
• @eldo That's exactly what I was looking for! Commented Aug 9, 2017 at 19:41