2009-12-09 11 views
18

Gibt es einen besseren Weg, dies zu tun? Ich brauche die Liste nicht wirklich, um sortiert zu werden, sondern um durchzugehen, um das Objekt mit dem größten spezifizierten Attribut zu erhalten. Ich sorge mich am meisten über die Lesbarkeit, aber das Sortieren einer ganzen Liste, um ein Element zu bekommen, scheint ein wenig verschwenderisch zu sein.Pythonischer Weg, um das größte Element in einer Liste zu bekommen

>>> import operator 
>>> 
>>> a_list = [('Tom', 23), ('Dick', 45), ('Harry', 33)] 
>>> sorted(a_list, key=operator.itemgetter(1), reverse=True)[0] 
('Dick', 45) 

Ich konnte es ganz verbosely tun ...

>>> age = 0 
>>> oldest = None 
>>> for person in a_list: 
...  if person[1] > age: 
...    age = person[1] 
...    oldest = person 
... 
>>> oldest 
('Dick', 45) 

Antwort

46
max(a_list, key=operator.itemgetter(1)) 
+0

Nizza, wusste nicht, dass Max ein optionales Schlüsselargument hatte! – Noah

+1

Ah, brilliant! Gute Python macht mich glücklich. –

7

Sie konnten die max-Funktion verwenden.

Hilfe auf integrierte Funktion max in Modul __builtin__:

max (...)

max (iterable [, key = func]) -> Wert

max (a, b, c, ... [, Schlüssel = func]) -> Wert

Mit einem einzigen iterablen Argument, geben Sie das größte Element zurück. Mit zwei oder mehr Argumenten das größte Argument zurückgeben.

max_item = max(a_list, key=operator.itemgetter(1)) 
2

Verwenden Sie die max() Funktion oder tun es FP-Stil:

reduce(lambda max, c: max if c <= max else c, [1, 6, 9, 2, 4, 0, 8, 1, 3]) 
5

Der Schlüssel auch eine Lambda, zum Beispiel sein:

people = [("Tom", 33), ("Dick", 55), ("Harry", 44)] 
oldest = max(people, key=lambda p: p[1]) 

Aus irgendeinem Grund ein mit Lambda lässt es eher wie "mein Code" wirken, verglichen mit itemgetter. Ich denke, das fühlt sich besonders schön, wenn man eine Sammlung von Objekten haben:

class Person(object): 
    def __init__(self, name, age): 
     self.name = name 
     self.age = age 

people = [Person("Tom", 33), Person("Dick", 55), Person("Harry", 44)] 
oldest = max(people, key=lambda p: p.age) 
0

Einige Leute die folgende Lösung gefunden:

max(nameOfList, key=len) 

Diese Lösung ist jedoch nur liefert das erste sequentielle Element der größten Größe. So wird beispielsweise im Falle der Liste ["ABC", "DCE"] nur das erste Element der Liste zurückgegeben.

Um dies zu beheben, fand ich die folgende Abhilfe mit der Filterfunktion:

filter((lambda x: len(x)==len(max(nameOfList, key=len))),nameOfList) 
Verwandte Themen