7

如何获得下一个最小值到 python 中提供的值?它有任何内置功能吗?

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

如何找到 3 的下一个最低值或 2 的下一个最大值?预期结果分别为 2 和 3。

4

7 回答 7

6

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获取时间,numpy对于前面示例的 100000 个元素数组/列表,我有 871 µs 使用和 13.8 ms 使用常规列表.

HTH, ciao


后经

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

于 2015-04-06T13:33:34.143 回答
5

我看到您的问题被标记为 [下限] 和 [上限]。如果您的列表已排序,则 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
于 2015-04-06T13:14:48.120 回答
3

次低至 3:

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

仅次于 2:

min([x for x in num_list if x > 2])
于 2015-04-06T13:12:40.763 回答
1

您可以使用sorted

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

但是,正如 Frerich Raabe 在评论中所说的那样,作为一种更 Pythonic 的方式,您不需要对整个列表进行酸痛,您可以在低于 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
于 2015-04-06T13:06:31.407 回答
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]
于 2015-04-06T17:17:09.027 回答
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)
于 2015-04-06T13:07:33.513 回答
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
>>> 
于 2015-04-06T13:12:52.960 回答