2010-05-04 6 views
15

Was ist die idiomatische Art zu tun maximumBy (Funktion höherer Ordnung nimmt eine Vergleichsfunktion für den Test), auf einer Liste von Listen, wo der Vergleich wir machen wollen die Summe der Liste, in Python?Suche nach dem Maximum einer Liste von Listen nach der Summe der Elemente in Python

Hier ist ein Haskell Implementierung und Beispielausgabe:

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

und Implementierungen dieser Basisbibliotheksfunktionen, nur der Vollständigkeit halber (falls Sie reduzieren oder etwas verwenden wollen :)

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 

Antwort

42

Seit Python 2.5 können Sie max mit einem Schlüsselparameter verwenden:

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

Haha, tolle Lösung! –

+3

+1. Kurz, klar und präzise. Sehr pythonisch. –

+1

max (a) scheint das Gleiche zu tun. – titaniumdecoy

1

Es ist nicht sehr effizient, aber:

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

Vergleicht man dies mit der richtigen Antwort von @Mark ist eine wunderbare Möglichkeit zu zeigen, warum Python-Programmierer bei weitem am besten _forgetting_ über 'reduce' wären (gut, dass es in Py3 nicht mehr eingebaut ist! -). –

+6

@Alex: Wenn jemand eine Antwort mit einer For-Schleife gepostet hätte, was auch viel unhandlicher gewesen wäre als Marks Antwort, hättest du argumentiert, dass Python-Programmierer lieber For-Schleifen vergessen sollten? – sepp2k

+2

@ sepp2k: 'for' Schleifen sind eine wunderbare Möglichkeit zu zeigen, warum Python-Programmierer List Comprehensions verwenden sollten. In aller Ernsthaftigkeit gibt es nicht immer einen Ersatz für eine "for" -Schleife, aber für "reduce" ist das normalerweise nicht der Fall. So sehr mir auch die 'map' /' filter'/'reduces' Trinity persönlich gefällt, Alex hat recht damit, dass es normalerweise einen besseren Weg gibt. – outis

1

Wenn max hat den Schlüssel Parameter nicht Sie die DSU Muster explizit codieren könnten:

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

izip und imap sind vom itertools Modul in Python 2 und tun, was Zip und Map tun, aber faul mit Python-Generatoren, um eine Zwischenliste zu vermeiden. In Python 3 sind die Map- und Zip-Builtins faul.