你如何迭代并保持前10名?蟒蛇

时间:2013-07-08 12:32:30

标签: python

我有一个需要从函数计算的数字列表。我需要计算2百万次。我本可以这样做,但有一种更简单的方法:

def funcx(): 
  return random.random() # for simplicity we use random

top10 = [] # max len = 10
for i in range(2000000):
  j = funcx()
  top10.append(j)
  top10 = sorted(top10, reverse=True)[:10]

3 个答案:

答案 0 :(得分:2)

使用固定大小的堆,而不是每次都对列表​​进行排序:

import heapq
top10=[]
for i in range(2000000):
    heapq.heappush(top10, funcx())
    top10 = top10[:10]

渐近地,运行时间是相同的,但应该有更少的开销。

另一个选择是使用nsmallest功能:

heapq.nsmallest(10, (funcx() for i in range(2000000)) )

这比简单地对列表进行排序并返回前10个项目效率低,但它应该(即,我没有检查)使用更少的内存。

答案 1 :(得分:1)

我想使用固定大小的堆显示正确的解决方案(accepted answer 不正确)。 假设您想要 10 个最小的元素。然后您可以使用最大堆并在每次推送后执行弹出。 pop 将删除最大的元素,留下 10 个最小元素的数组。有均匀有效的操作heapq.heappushpop。 10 个最小元素的代码如下所示:

import heapq
top10 = []
for i in range(2000000):
    # Heapq implements min heap, so we need to negate the numbers
    heapq.heappushpop(top10, -funcx())
print(top10)

无论如何,这段代码与 heapq.nsmallest 的实现基本相同(它处理一些额外的极端情况,例如 n == 1),因此您最好使用它:

heapq.nsmallest(10, (funcx() for i in range(2000000)))

heap.nlargest 个最大的元素。

答案 2 :(得分:0)

正如另一位用户指出的那样,我还建议实现插入排序。但是,正如您目前所拥有的那样。您只需查找最大值并将其从列表中删除,然后重复10次。

>>> x = [1,2,3,4,5]
>>> max(x)
5
>>> x.remove(5)
>>> max(x)
4