2014-03-01 59 views

回答

7

您可以使用heapq.nsmallest

>>> from heapq import nsmallest 
>>> in_list = [1, 2, 3, 4, 5, 6] 
>>> nsmallest(3, in_list) 
[1, 2, 3] 
>>> 
1

如果你的名单很长,这样做的最有效的方法是通过numpy.partition

>>> def lowest(a, n): return numpy.partition(a, n-1)[:n] 
>>> in_list = [6, 4, 3, 2, 5, 1] 
>>> lowest(in_list, 3) 
array([1, 2, 3]) 

此执行O(N)时间,不同于全排序这将在O(NlogN)时间运行。节省的时间来自未执行完整排序,但只有确保最低元素排在第一位所需的最小量。因此,输出不一定是排序的。

如果您需要对它们进行排序,则可以在此后执行此操作(numpy.sort(lowest(in_list,3)) => array([1,2,3]))。对于大数组,这仍然比首先排序整个事物更快。

编辑:以下为numpy.partitionheapq.nsmallestsorted速度的比较:

>>> a = numpy.random.permutation(np.arange(1000000)) 
>>> timeit numpy.partition(a, 2)[:3] 
100 loops, best of 3: 3.32 ms per loop 
>>> timeit heapq.nsmallest(3,a) 
1 loops, best of 3: 220 ms per loop 
>>> timeit sorted(a)[:3] 
1 loops, best of 3: 1.18 s per loop 

所以numpy.partitionheapq.nsmallest更快用于与一百万个元素的数组66倍,它比快355倍sorted。这并不意味着你永远不应该使用heapq.nsmallest(这是非常灵活的),但它表明,当速度很重要时避免简单列表是多么重要。

+0

这会将原始列表转换为一个'np.array()'对象。 –

+0

请注意,heapq.nsmallest()会按照大致相同的顺序执行相同的操作,加上排序,它需要O(NlogK)时间,其中K是要返回的元素的数量。 'numpy.partition()'和'heapq'都由C代码支持。 heapq然后返回一个Python列表的事实可以被看作是优于'numpy.partition()'的优势。 –

+0

是的。但是,如果你的列表很长,你想要使用数组而不是列表,因为它们速度更快并且使用更少的内存。如果你想让输出成为一个普通的列表,只需要执行'list(lowest(in_list,3))'。 – amaurea

3

如果你能排序,你可以得到FRST如下3个要素:

alist=[6, 4, 3, 2, 5, 1] 
sorted(alist)[:3] 

输出:

[1,2,3] 
1

更简单,而不导入模块:

l =[3,8,9,10,2,4,1] 
l1 = sorted(l)[:3] 

希望这有助于

相关问题