Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Say I have a list x={2,4,6,8,10} and I want to find out the positions of the elements that are greater than 7.

Select[x, #>7&] gives the elements themselves, and Position[x,8] gives the position of the elements satisfying one of the possible criteria, but what I am looking for would be a mix of the two returning {4,5}.

Any suggestions?

share|improve this question
1  
Using ogerard's processing idea, one can use Pick to enhance performance: x = {2, 4, 6, 8, 10}; Pick[Range[Length[x]], Sign[x - 6], 1]. –  Sasha Jan 18 '12 at 20:46
1  
I've noticed a preference for people below to use PatternTest rather than Condition. Are any performance differences or is it just what people are used to? –  Mike Honeychurch Jan 18 '12 at 22:15
    
I prefer Condition for ease of naming elements to work with them. –  Brett Champion Jan 19 '12 at 1:05
add comment

6 Answers 6

up vote 16 down vote accepted

Position[{2, 4, 6, 8, 10}, _?(# > 7 &)] does the job. Apply Flatten[] if need be.

share|improve this answer
3  
You can also preprocess the list, like this Position[{2, 4, 6, 8, 10} - 6, _?Positive] –  ogerard Jan 18 '12 at 18:15
    
@ogerard, post it as an answer. –  rcollyer Jan 18 '12 at 18:18
    
This answer is not correct. Just in case people get this far and don't scroll down, check @brett champion's answer below first. –  Dan Piponi Apr 11 at 22:56
add comment

Position can take very generic patterns. Here we ask for the position of values in the list given that they are larger than 7.

x={2,4,6,8,10};

In[11]:= Position[x,val_/;val>7]
Out[11]= {{4},{5}}
share|improve this answer
add comment

As many have pointed out, Position can be used for this, but you may want to take care since Position will quite happily go into things you might not expect it to.

In[17]:= Position[Sin[{2, 4, 6, 8, 10}], _?(# > 0.5 &)]

Out[17]= {{1, 1}, {1}, {2, 1}, {3, 1}, {4, 1}, {4}, {5, 1}}

Note that we got match from the 4 in Sin[4] being bigger than 0.5, even though numerically Sin[4] around -0.75. We can use a level specification to limit the depth at which we're inspecting elements:

In[18]:= Position[Sin[{2, 4, 6, 8, 10}], _?(# > 0.5 &), 1]

Out[18]= {{1}, {4}}
share|improve this answer
add comment

A couple of options come to mind, but I think Position can be manipulated into giving you what you want. The key is to use a PatternTest, as follows

Position[x, _?(#>7&)] // Flatten

returns

{4, 5}.

For another variant, MapIndexed can be used directly

MapIndexed[If[#1 > 7, #2, Unevaluated[Sequence[]]] &, {2, 4, 6, 8, 10}]

which relies on the properties of an empty Sequence in a List. The Unevaluated is necessary to unsure that you don't get Null in the list.

share|improve this answer
2  
Nice trick with Unevaluated[Sequence[]] to have the kernel contract the list ! –  ogerard Jan 18 '12 at 22:50
add comment

Position is certainly the best for the job, but for the sake of completeness, you can do this in a way similar to Select:

DeleteCases[MapIndexed[If[#1 > 7, #2] &, {2, 4, 6, 8, 10}], Null]

While inefficient when you select only on content, this form allows to mix criteria on the content and position.

share|improve this answer
add comment

As others have said, Position does the job:

lst = {2, 4, 9, 6, 8, 10};
posns=Position[lst, _?(# > 7 &)]
(*
{{3}, {5}, {6}}
*)

This is now in the appropriate form for Extract:

Extract[lst, posns]
(*
{9, 8, 10}
*)
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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