2009-12-09 55 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

不錯,不知道有最多可選關鍵參數! – Noah 2009-12-09 14:23:29

+1

啊,輝煌!好的python讓我開心。 – 2009-12-09 14:24:20

7

你可以使用max功能。

幫助上內置函數max在模塊__builtin__:

最大值(...)

MAX(可迭代[,鍵= FUNC]) - >值

MAX( 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

的關鍵也可以是一個lambda,例如:

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) 
相關問題