如果列表很短,那么正如其他人建议的那样,您可以对其进行排序和切片。如果列表非常大,那么您最好使用heapq.nlargest()
:
>>> import heapq
>>> lis = [['Mumbai', 98.3], ['London', 23.23], ['Agra', 12.22]]
>>> heapq.nlargest(2, lis, key=lambda x:x[1])
[['Mumbai', 98.3], ['London', 23.23]]
不同之处在于 nlargest 仅通过列表一次,事实上,如果您正在从文件或其他生成的源中读取,则不必同时都在内存中。
您可能也有兴趣查看源代码,nlargest()
因为它的工作方式与您尝试解决问题的方式大致相同:它仅在称为堆的数据结构中保留所需数量的元素,并且推送每个新值进入堆,然后从堆中弹出最小值。
编辑以显示比较时间:
>>> import random
>>> records = []
>>> for i in range(100000):
value = random.random() * 100
records.append(('city {:2.4f}'.format(value), value))
>>> import heapq
>>> heapq.nlargest(10, records, key=lambda x:x[1])
[('city 99.9995', 99.99948904248298), ('city 99.9974', 99.99738898315216), ('city 99.9964', 99.99642759230214), ('city 99.9935', 99.99345173704319), ('city 99.9916', 99.99162694442714), ('city 99.9908', 99.99075084123544), ('city 99.9887', 99.98865134685201), ('city 99.9879', 99.98792632193258), ('city 99.9872', 99.98724339718686), ('city 99.9854', 99.98540548350132)]
>>> timeit.timeit('sorted(records, key=lambda x:x[1])[:10]', setup='from __main__ import records', number=10)
1.388942152229788
>>> timeit.timeit('heapq.nlargest(10, records, key=lambda x:x[1])', setup='import heapq;from __main__ import records', number=10)
0.5476185073315492
在我的系统上,通过排序和切片从 100 条记录中获得前 10 条是最快的,但是对于 1000 条或更多记录,使用 nlargest 更快。