如果我有一个列表list1=[1,15,9,3,6,21,10,11]
,如何从中获得最小的2个整数?
min()
给了我一个号码,但是2呢?
答案 0 :(得分:3)
您可以导入heapq
import heapq
list1=[1,15,9,3,6,21,10,11]
print(heapq.nsmallest(2,list1))
这方面的限制是,如果您有重复值,请说l=[1,3,5,1]
,则两个最小值将为[1,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
从两者来看,似乎对较小的集合进行排序更快。
编辑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
感谢Padraic Cunningham,heapq
使用更大的集合更快
答案 1 :(得分:3)
您可以对列表进行排序并获取前两个元素:
sorted(list1)[:2]
或者,删除min并找到下一个min(这应该是大型数据集的最快解决方案,因为它最多需要3次传递):
list1=[1,15,9,3,6,21,10,11]
m1 = min(list1)
list1.remove(m1)
m2 = min(list1)
print m1, m2 # 1 3
答案 2 :(得分:1)
使用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)
list1=[1,1,9,3,6,21,10,11]
最小的是骗局,他仍然会返回1,3
,其中nsmallest会返回1,1
,这是值得注意的。
您也可以在列表中一次性完成,因为您没有欺骗行为:
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
哪个会比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
如果你确实想要处理欺骗行为:
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
哪个会得到忽略重复的两个最小数字:
In [48]: list1 = [12, 15, 3, 3, 6, 21, 10, 11]
In [49]: min_two_dupes(list1)
Out[49]: (3, 6)
运行效率很高:
In [52]: timeit min_two_dupes(list1)
100 loops, best of 3: 9.04 ms per loop
答案 3 :(得分:1)
你想先n还是2?这是获得列表中2个第一低数字的一种方法:
list1=[1,15,9,3,6,21,10,11]
list1.sort()
twoFirst = list1[:2]
nFirst = list1[:n]
在我写答案时,我可能正在删除我的回答。如果存在相关重复,则多次返回相同的数字。
答案 4 :(得分:0)
如果您的列表不能包含重复项,则可以使用heapq:
from heapq import nsmallest
list1=[1,15,9,3,6,21,10,11]
smallest = nsmallest(2, list1)
如果可以,您可以对列表进行排序,然后对其进行切片:
smallest = sorted(list1)[0:2]