2010-05-04 4 views
15

Что такое идиоматический способ сделать maximumBy (функция более высокого порядка, использующая функцию сравнения для теста), в списке списков, где сравнение, которое мы хотим сделать, это сумма списка, в Python?Поиск максимального списка списков по сумме элементов в Python

Вот Haskell реализация и пример вывод:

> maximumBy (compare `on` sum) [[1,2,3],[4,5,6],[1,3,5]] 
> [4,5,6] 

И реализация этих базовых функций библиотеки, просто для полноты картины (в случае, если вы хотите использовать уменьшить или что-то :)

maximumBy cmp xs = foldl1 maxBy xs 
    where 
     maxBy x y = case cmp x y of GT -> x; _ -> y 

k `on` f = \x y -> f x `k` f y 

sum  = foldl' (+) 0 

ответ

42

С Python 2.5 вы можете использовать max с ключевым параметром:

>>> max(a, key=sum) 
[4, 5, 6] 
+0

Ха-ха, удивительное решение! –

+3

+1. Короткие, четкие и точные. Очень pythonic. –

+1

max (a) похоже на то же самое. – titaniumdecoy

1

Это не очень эффективно, но:

reduce(lambda x,y: x if sum(x)>sum(y) else y, [[1,2,3],[4,5,6],[1,3,5]]) 
+0

Сравнивая это с правильным ответом @ Mark, это восхитительный способ показать, почему программисты на Python были бы лучше всего _forgetting_ о 'reduce' (хорошо, что это не встроенный в Py3! -). –

+6

@Alex: Если бы кто-то отправил ответ, используя for-loop, который также был бы намного более неудобным, чем ответ Марка, вы бы утверждают, что программисты на питонах лучше забывают о for-loops? – sepp2k

+2

@ sepp2k: 'for' loops - восхитительный способ показать, почему программисты Python должны использовать списки. Во всей серьезности не всегда есть замена для цикла 'for', но обычно это не так для' reduce'. Насколько мне лично нравится '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' – outis

1

Если Макс не было ключевой параметр можно закодировать шаблон DSU явно:

max(izip(imap(sum,a),a))[1] 

izip и imap находятся из модуля itertools в python 2 и делать то, что делают zip и map, но лениво с помощью генераторов Python, чтобы избежать получения промежуточного списка. В Python 3 карты и встроенные zip-серверы ленивы.