[英]Smallest n numbers from a list
If I have a list list1=[1,15,9,3,6,21,10,11]
how do I obtain the smallest 2 integers from that?如果我有一个列表
list1=[1,15,9,3,6,21,10,11]
我如何从中获得最小的 2 个整数?
min()
gives me one number, but what about 2? min()
给了我一个数字,但是 2 呢?
You can sort the list and grab the first two elements:您可以对列表进行排序并获取前两个元素:
sorted(list1)[:2]
Or, remove the min and find the next min (which should be the quickest solution for large datasets because it requires 3 passes at most):或者,删除最小值并找到下一个最小值(对于大型数据集,这应该是最快的解决方案,因为它最多需要 3 次通过):
list1=[1,15,9,3,6,21,10,11]
m1 = min(list1)
list1.remove(m1)
m2 = min(list1)
print m1, m2 # 1 3
You can import heapq你可以导入heapq
import heapq
list1=[1,15,9,3,6,21,10,11]
print(heapq.nsmallest(2,list1))
The limitation with that is if you have a repeated value let's say l=[1,3,5,1]
, the two smallest values will be [1,1]
.这样做的限制是,如果你有一个重复的值,比如说
l=[1,3,5,1]
,两个最小值将是[1,1]
。
Edit 1:编辑1:
In [2]:
list1=[1,15,9,3,6,21,10,11]
In [3]:
%timeit sorted(list1)[:2]
1000000 loops, best of 3: 1.58 µs per loop
In [5]:
import heapq
%timeit heapq.nsmallest(2,list1)
100000 loops, best of 3: 4.18 µs per loop
From the two, it seems sorting the list is faster for smaller sets.从两者来看,对于较小的集合,似乎对列表进行排序更快。
Edit 2:编辑2:
In [14]:
import random
list1=[[random.random() for i in range(100)] for j in range(100)]
In [15]:
%timeit sorted(list1)[:2]
10000 loops, best of 3: 55.6 µs per loop
In [16]:
import heapq
%timeit heapq.nsmallest(2,list1)
10000 loops, best of 3: 27.7 µs per loop
Thanks to Padraic Cunningham, heapq
is faster with larger sets感谢 Padraic Cunningham,
heapq
在更大的集合中更快
Using min and two passes over list1:使用 min 和两次遍历 list1:
list1=[1,15,9,3,6,21,10,11]
mn = min(list1)
mn2 = min(i for i in list1 if i != mn)
print((mn,mn2))
(1, 3)
It list1=[1,1,9,3,6,21,10,11]
where the smallest was a dupe, his would still return 1,3
where nsmallest would return 1,1
so that is something to be aware of.它
list1=[1,1,9,3,6,21,10,11]
其中最小的是一个骗子,他仍然会返回1,3
而 nsmallest 会返回1,1
所以这是需要注意的事情。
You can also do it in one pass over the list since you have no dupes:您也可以在列表中一次性完成,因为您没有受骗者:
def min_two(lst):
mn1, mn2 = float("inf"),float("inf")
for ele in lst:
if ele < mn1:
mn1 = ele
continue
if ele < mn2:
mn2 = ele
return mn1, mn2
Which will be faster than a heapq.nsmallest
:这将比
heapq.nsmallest
更快:
In [34]:list1=[random.random() for j in range(10**5)]
In [35]: timeit heapq.nsmallest(2,list1)
100 loops, best of 3: 11.6 ms per loop
In [36]: timeit min_two(list1)
100 loops, best of 3: 9.01 ms per loop
In [37]: %timeit sorted(list1)[:2]
10 loops, best of 3: 42.2 ms per l
And if you did actually want to handle dupes:如果您确实想处理欺骗行为:
def min_two_dupes(lst):
mn1, mn2 = float("inf"),float("inf")
for ele in lst:
if ele < mn1:
mn1 = ele
continue
if ele < mn2 and ele != mn1:
mn2 = ele
return mn1, mn2
Which will get the two lowest numbers ignoring repeats:这将得到两个最小的数字,忽略重复:
In [48]: list1 = [12, 15, 3, 3, 6, 21, 10, 11]
In [49]: min_two_dupes(list1)
Out[49]: (3, 6)
And runs just as efficiently:并且运行同样有效:
In [52]: timeit min_two_dupes(list1)
100 loops, best of 3: 9.04 ms per loop
you want the n first or 2 first?你想先 n 还是先 2? this is one way to get the 2 first lowest numbers in a list:
这是获取列表中前 2 个最低数字的一种方法:
list1=[1,15,9,3,6,21,10,11]
list1.sort()
twoFirst = list1[:2]
nFirst = list1[:n]
I am probably deleting my answer as someone suggested while I was writing my answer.在我写答案时,我可能会按照某人的建议删除我的答案。 This was return the same number multiple times if there are relevant duplicates.
如果有相关的重复,这将多次返回相同的数字。
If your list can't contain duplicates, you could use heapq:如果您的列表不能包含重复项,您可以使用 heapq:
from heapq import nsmallest
list1=[1,15,9,3,6,21,10,11]
smallest = nsmallest(2, list1)
If it can, you could sort the list and then slice it:如果可以,您可以对列表进行排序,然后对其进行切片:
smallest = sorted(list1)[0:2]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.