Find second largest elements in list
One way, not highly efficient:
lis = {37.21, 37.21, 37.2, 44, 44, 44, 101, 101};
lis ~Cases~ Union[lis][[-2]]
{44, 44, 44}
This should be a bit more efficient:
ConstantArray @@ Sort[Tally@lis][[-2]]
Caveat: both of these methods rely on sorting and therefore require numeric data.
flinty's method with refinements by both C. E. and me:
Pick[lis, lis, RankedMax[DeleteDuplicates@lis, 2]]
This appears to be the fastest overall and it avoids the sorting issue referenced above.
Benchmarking
A quick test of the methods posted so far reveals an interesting pattern. Note that in the benchmark I use a list of a fixed length of one million and vary the number of unique elements within that list.
Adding methods f5, f6, and f7, and a second test with unpackable data.
Performed in Mathematica 10.1
Needs["GeneralUtilities`"]
SetOptions[Benchmark, TimeConstraint -> 30];
f1[lis_] := lis ~Cases~ Union[lis][[-2]]
f2[lis_] := ConstantArray @@ Sort[Tally@lis][[-2]]
f3[lis_] := MaximalBy[DeleteCases[lis, Max@lis], # &] (* Conor/kglr *)
f4[lis_] := Split[Sort@lis][[-2]] (* kglr *)
f5[lis_] := Pick[lis, lis - RankedMax[DeleteDuplicates@lis, 2], 0]; (* flinty/C. E. *)
f6[lis_] := Extract[List/@KeySort[PositionIndex[lis]][[-2]]][lis] (* CA Trevillian *)
f7[lis_] := Pick[lis, lis, RankedMax[DeleteDuplicates@lis, 2]] (* flinty/C.E./me *)
BenchmarkPlot[{f1, f2, f3, f4, f5, f6, f7},
RandomInteger[#, 1*^6] &, 10^Range[6], Joined -> True]
BenchmarkPlot[{f1, f2, f3, f4, f5, f6, f7},
Prepend[0.5]@RandomInteger[#, 1*^6] &, 10^Range[6], Joined -> True]
another way...
MaximalBy[DeleteCases[lis, Max@lis], # &]
{44, 44, 44}
Split[ Sort @ lis][[-2]]
{44, 44, 44}
Also
Nearest[DeleteCases[Max @ #] @ #, Max @ #] & @ lis
{44, 44, 44}