Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the best way to select the maximum one from a list of lists by their last element?

In Mathematica, Max[] is the most efficient function to get the maximum number in a list of numbers, but how do I find the list with the maximum last element in a list of lists? e.g. the 2-d coordinate with the biggest x part in a series of coordinates.

My best try is SortBy, but obviously I don't need the program to sort my list, only the maximum one I need.

like image 800
xzhu Avatar asked Jul 12 '11 03:07

xzhu


People also ask

How do you find the max of a list in a list?

The max() Function — Find the Largest Element of a List. In Python, there is a built-in function max() you can use to find the largest number in a list. To use it, call the max() on a list of numbers. It then returns the greatest number in that list.

What is the correct way to get maximum value from a list in Python?

Python max() Function The max() function returns the item with the highest value, or the item with the highest value in an iterable.

Which function returns the maximum value in a list?

The Math.max() function returns the largest of the numbers given as input parameters, or - Infinity if there are no parameters.

Does Max work on lists Python?

Python has an in-built max function that you can use to locate the maximum value in an iterable. For example, if we call the max function in a list of strings, it returns the last item with the strings arranged in alphabetical order.


3 Answers

Perhaps:

list = {{4, 3}, {5, 10}, {-2, 1}, {3, 7}}

Reverse /@ Take[#, Ordering[#, -1]] &@(Reverse /@ #) &@ list
(*
-> {{5, 10}}
*)

Exploiting the fact that Ordering[ ] orders lists by their first element

Edit

Or much better (I think):

Take[#, Ordering[Last /@ #, -1]] &@ list

Edit

Also:

#[[Ordering[#, -1, Last@#2 > Last@#1 &]]] &@list

Edit

Perhaps faster:

#[[First@Position[#, Max@#] &@(Last /@ #)]] &@list
like image 157
Dr. belisarius Avatar answered Oct 24 '22 11:10

Dr. belisarius


Here is my approach using Pick

maxBy[list_, n_] := With[{s = list[[All, n]]}, Pick[list, s, Max[s]]]

maxBy[{{4, 3}, {5, 10}, {-2, 1}, {3, 7}}, 2]

(* output: 
  {{5, 10}}  
*)

This version works on any number of elements per sublist provided n is less than or equal to the length of the shortest sublist.

Timings for this version on my machine

list2 = RandomInteger[{-10^7, 10^7}, {10^6, 2}];
list3 = RandomInteger[{-10^7, 10^7}, {10^6, 3}];
list9 = RandomInteger[{-10^7, 10^7}, {10^6, 9}];

maxBy[list2, 2]; // Timing
maxBy[list3, 2]; // Timing
maxBy[list9, 2]; // Timing

(* output: 
  {0.030341, Null}  
  {0.030912, Null}  
  {0.033313, Null}  
*)

Compared to David's code

maxBy[list2, 2]; // Timing
maxBy[list3, 2]; // Timing
maxBy[list9, 2]; // Timing

(* ouput:
  {0.186175, Null}  
  {0.184989, Null}  
  {0.262018, Null}  
*)

Yoda's code

maxBy[list2, 2]; // Timing
maxBy[list3, 2]; // Timing
maxBy[list9, 2]; // Timing

(* ouput:
  {0.944016, Null}
  {0.83094, Null}
  {0.874126, Null}
*)

And belisarius' code

Reverse /@ Take[#, Ordering[#, -1]] &@(Reverse /@ #) &@list2; // Timing
Take[#, Ordering[Last /@ #, -1]] &@list2; // Timing
#[[Ordering[#, -1, Last@#2 > Last@#1 &]]] &@list2; // Timing
#[[First@Position[#, Max@#] &@(Last /@ #)]] &@list2; // Timing 

(* output:
  {0.211016, Null}
  {0.099253, Null}
  {2.03415, Null}
  {0.266934, Null}
*)
like image 21
Heike Avatar answered Oct 24 '22 11:10

Heike


How about this function (defined here only for 2D lists):

maxBy = Module[{pattern = Reverse@Insert[{Max@#1[[All, #2]]}, _, #2]},
               Cases[#1, pattern]] &

Example:

list = {{4, 3}, {5, 10}, {20, 1}, {3, 7}};

maxBy[list, 1]    
Out[1]= {{20, 1}}

maxBy[list, 2]  
Out[2]= {{5, 10}}
like image 22
abcd Avatar answered Oct 24 '22 11:10

abcd