2009-12-09 3 views
18

Есть ли лучший способ сделать это? Мне не нужен список, который нужно сортировать, просто просматривая его, чтобы получить элемент с наибольшим указанным атрибутом. Мне больше всего нравится чтение, но сортировка всего списка, чтобы получить один элемент, кажется немного расточительным.Pythonic способ получить самый большой элемент в списке

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

я мог сделать это довольно пространно ...

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

ответ

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

Nice, не знал, что Макс был дополнительный ключевой аргумент! – Noah

+1

Ах, блестящий! Хороший питон делает меня счастливым. –

7

Вы можете использовать функцию max.

Помощь по встроенной функции макс в модуле __builtin__:

макс (...)

макс (итерацию [, ключ = FUNC]) -> значение

макс (a, b, c, ... [, key = func]) -> значение

С помощью единственного итеративного аргумента верните самый большой элемент. С двумя или более аргументами верните самый большой аргумент.

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

Используйте функцию max() или сделать это FP стиль:

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

Ключ также может быть лямбда, например:

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

По какой-то причине, используя lambda заставляет его больше походить на то, что «мой код» делает работу, по сравнению с itemgetter. Я думаю, что это чувствует себя особенно хорошо, когда у вас есть коллекция объектов:

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

Некоторые люди упомянули следующее решение:

max(nameOfList, key=len) 

Однако это решение возвращает только первый последовательный элемент большого размера. Так, например, в случае списка ["ABC", "DCE"] возвращается только первый элемент списка.

Чтобы исправить это, я нашел следующий обходной путь с помощью функции фильтра:

filter((lambda x: len(x)==len(max(nameOfList, key=len))),nameOfList) 
Смежные вопросы