7
$\begingroup$

Let's say I have the following list:

L = {2,4,6,8,10}

How can I get Mathematica to find the index position of the first value in the list that is over 4 (6 in this case). I tried Position[L, L > 4], but this gave no output. Any help would be appreciated.

$\endgroup$
0

3 Answers 3

10
$\begingroup$

In version 10 there is a new function FirstPosition:

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

FirstPosition[ L, x_ /; x > 4]
{3}

The second argument of Position as welll as of FirstPosition is a pattern, so this would yield what you seemed to expect:

Position[ L, x_ /; x > 4]
{{3}, {4}, {5}}
$\endgroup$
1
  • 1
    $\begingroup$ Note that as given above, FirstPosition will apply at all levels (including the list as a whole) and at the list head: FirstPosition[{2, 4, 6, 8, 10}, x_ /; (Print[x]; x > 12)] prints List, 2, 4, 6, 8, 10, {2,4,6,8,10}. To get the expected behavior of only iterating over the list elements, you have to do something like FirstPosition[{2, 4, 6, 8, 10}, x_ /; x > 12, Null, {1}, Heads -> False] (or make the pattern more restrictive). $\endgroup$ Jan 7, 2023 at 22:19
6
$\begingroup$

Just for interest:

pos[lst_] := First@Position[lst, _?(# > 4 &)];
fp[lst_] := FirstPosition[lst, _?(# > 4 &)];
nw[lst_] := NestWhile[# + 1 &, 1, lst[[#]] <= 4 &]
w[lst_] := Module[{n = 1}, While[lst[[n]] <= 4, n++]; n]

Comparing:

Needs["GeneralUtilities`"]
bmp = Quiet@
  BenchmarkPlot[{pos, fp, nw, w}, RandomInteger[{-10, 10}, #] &, 
   PowerRange[10, 1000000], "IncludeFits" -> True]

enter image description here

$\endgroup$
6
  • $\begingroup$ While this comparison is interesting I don't believe it represents a correct picture of relative efficiency. Do you really belive that NestWhile or While are more efficient than FirstPosition? I guess it is just an artefact of very special data you work with. In more general situation FirstPosition should be definitely faster, otherwise I can't see any argument for introducing this function to the system. $\endgroup$
    – Artes
    Nov 4, 2014 at 13:15
  • $\begingroup$ @Artes Currently for WRI the verbosity of the language is an argument for introducing new functions. In the view of this fact the comparisons like in this answer become especially valuable. $\endgroup$ Nov 4, 2014 at 14:05
  • $\begingroup$ @AlexeyPopkov As you might observe random long lists out of a $21$-element set is very special choice which obviously rewards methods based on NestWhile or While. So it should be quite simple to point out different data where FirstPosition is much better even for long lists. This is what I meant in my former comment. $\endgroup$
    – Artes
    Nov 4, 2014 at 14:33
  • $\begingroup$ @Artes I'm not familiar with the notation $21$. What does it mean? Could you give an example where FisrtPosition has better performance than other methods? $\endgroup$ Nov 4, 2014 at 14:41
  • $\begingroup$ @AlexeyPopkov He's chosen RandomInteger[{-10, 10}, n] i.e. as a list it is of length $n$ (it may be whatever you want) but there are only $21$ different elements. If you played with e.g. long lists of primes with special properties and you were to choose a very special number then FirstPosition should be much better. I have no time to provide appropriate tests but I guess now it should be clear what I mean. I believe you can find a good example otherwise I'll try tomorow. $\endgroup$
    – Artes
    Nov 4, 2014 at 14:54
4
$\begingroup$
L = {2, 4, 6, 8, 10};

f = 1 + LengthWhile[#, # <= 4 &] &;
(* or f = 1 + LengthWhile[#, Not[# > 4] &] &; *)
f@L
(* 3 *)

More generally,

f2 = Function[{lst, t}, 1 + LengthWhile[lst, Not[# > t] &]];
f2[L, 4]
(* 3 *)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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