2015-04-06 140 views
11

如何获得python中提供的值的下一个最小值?有没有内置的功能?获取python中的数字列表中的最小值

>>>num_list=[1,2,3,4] 
>>> min(num_list) 
1 
>>> max(num_list) 
4 

我怎样才能找到下一个最低到3或下一个最大到2?预期的结果是2和3。

+0

是列表排序? – 2015-04-06 13:10:30

回答

4

TL; DR要么min(n for n in my_list if n>lower_bound)max(n for n in my_list if n<upper_bound)


的简易求更快的替代直接最小即时最大numpy

>>> import numpy as np 
>>> np.random.seed(10) 
>>> a = np.random.random(10000) 
>>> a[a>0.7].min() 
0.69999533217645671 
>>> a[a<0.7].max() 
0.70003449227846715 

如果您使用的是numpy机械 ,并希望与清单只是处理

>>> a = list(a) 

,那么你可以使用minmax建宏随着发电机 表达

>>> min(n for n in a if n>0.7) 
0.69999533217645671 
>>> max(n for n in a if n<0.7) 
0.70003449227846715 
>>> 

使用您列出不舒服,当然,相同的结果,但要注意性能有所不同:使用ipython%timeit来获得时间,我有871微秒使用numpy和13.8毫秒使用常规列出前面例子的100000个元素数组/列表。

HTH,侨


邮政Scriptum

在回答这些解决方案都为O(n),与O相比(N log n)的的使用排序方法 - - 另外,对于大数据集numpy方法应该(斜体,因为我手边没有测试...)会受到一个小乘法因子的影响。

+0

'解决了我的问题,使用'min(n为n,如果n> m)。如果列表不是由'np.random.seed(n)'生成的,我可以将常规列表转换为输入'np.random.random()'吗? – cutteeth 2015-04-07 06:04:05

+1

在我的理解中,你问:“我有一个_regular_列表,并且出于速度的原因,我想使用'numpy''...但在我看来,你不熟悉'numpy',所以我的建议是“留在常规列表中”。如果你想学习相当多的新东西,这里是配方:''np',my_list = list_computing_function()','my_array = np.array(my_list)',最后'nearmin5 = my_array [ my_array> 5] .min()'但是请不要盲目应用它,在你的上下文中它甚至可能比列表解决方案慢。 – gboffi 2015-04-07 06:52:03

+0

可以吗?请删除答案的numpy部分?每当我收到关于相同的通知时,我都会检查这个答案。我认为最好去除numpy部分,或者将它移动到最小和最大部分之下,这是问题的适当答案。谢谢 :) – cutteeth 2017-05-07 18:24:27

1

您可以使用sorted

>>> l=sorted(num_list,reverse=True) 
>>> l[l.index(3)+1] 
2 

但作为一个更Python的方式Frerich拉贝在评论说,你不需要疮整个列表,你可以找到那些低于3元的最大值:

>>> max(i for i in num_list if i<3) 
2 

而对于2之后下一个最大的,你可以使用min

>>> min(i for i in num_list if i>2) 
3 
+1

排序整个列表是矫枉过正的。请注意,您只需查看一次输入列表的每个元素即可找到例如最小的元素比3小。这可以在线性时间内完成。 – 2015-04-06 13:23:32

+0

请注意,这也是越野车,因为你可能得到一个IndexError – Shashank 2015-04-06 13:29:31

+0

@FrerichRaabe是的,OP的问题使我远离这个优雅的!感谢提醒! – Kasramvd 2015-04-06 13:30:36

0

您可以使用以下方法:

num_list = [1,2,3,4] 
inds = sorted(range(len(num_list)), key=lambda k: num_list[k]) 

然后,INDS [1]将包含一个最低的元素的索引等。 此外,您可以使用下面的代码不排序:

minv = min(num_list)  
nmin = min(nm for nm in num_list if nm > minv) 
maxv = max(num_list) 
nmax = max(nm for nm in num_list if nm < maxv) 
+0

使用'sorted'是矫枉过正,第二个提议是O(n^2)。 – 2015-04-06 13:44:02

+0

你是对的,我纠正了我的答案。 – kvorobiev 2015-04-06 13:45:39

2

下一个最低至3:

max([x for x in num_list if x < 3]) 

下一个最大的以2:

min([x for x in num_list if x > 2]) 
+4

这里你不需要列表解析,即只有'max(x对于num_list中的x,如果x <3)'足够(并且更高效)。 – 2015-04-06 13:21:14

0

所提供的答案是好的,但如果我可以提出一个建议 - 如果有时候可以重复这些值的话,比如

num_list = [2, 2, 4, 4, 6, 7, 8, 9] 

...等等,只是对列表进行排序并获得第一个索引可能不是您要查找的内容。

使其通过一个set()第一,你会确保每个条目是单:

def sorted_ordered_list(sequence): 
    return sorted(list(set(sequence))) 

那么你可以只指数返回list为无论你正在寻找,从价值最低在索引0到最高。

实施例:

>>> my_list = [1, 5, 4, 3, 6, 3, 8, 3, 6, 7, 4, 2, 6, 7, 9, 8, 8] 
>>> sorted_ordered_list(my_list) 
[1, 2, 3, 4, 5, 6, 7, 8, 9] # now index the list for the desired value 
>>> 
+0

这是一种方式,但昂贵。考虑到原始问题可以在线性时间和固定空间内解决。 – wsysuper 2015-04-07 10:33:33

+0

当然,但它是一个单用途,使用零但内置,有点像OP要求 – 2015-04-07 13:40:51

3

我明白你的问题是标记[下限]和[上界。如果您的列表已排序,则Python具有等效的C++ <算法>的lower_boundupper_bound。他们在bisect模块中。他们返回一系列特定值的开始和结束后的索引。

In [1]: import bisect 

In [2]: A = [0, 1, 3, 3, 5] 

In [3]: A[bisect.bisect_left(A, 3)-1] 
Out[3]: 1 

In [4]: A[bisect.bisect_right(A, 3)] 
Out[4]: 5 
+0

我很抱歉的延迟答复,但我可以知道复杂性,请吗? – cutteeth 2017-05-07 18:17:35

+0

@cutteeth O(log n),但您的列表必须已经排序。 – 2017-05-08 00:59:23

1

使用heapq.nlargestheapq.nsmallest

import heapq 

num_list = [1, 2, 3, 4] 

heapq.nlargest(2, num_list) 
heapq.nsmallest(2, num_list) 
#>>> [4, 3] 
#>>> [1, 2]