我有一个包含已排序数字的列表L
。
我有一个x
,是任意的。我希望找到L
中<= x
的最大数字{{1}}。我可以通过一个循环来做到这一点,但如果有一个Pythonic单行或奇特的功能,我会很好奇。
答案 0 :(得分:3)
使用bisect
模块。与O(LogN)
的简单循环相比,此方法的复杂性为O(N)
。
>>> import bisect
def solve(lis, item):
ind = bisect.bisect_right(lis, item, hi = len(lis)-1)
return lis[ind] if lis[ind] <= item else lis[ind-1]
>>> L = range(10, 100)
>>> L.remove(15)
>>> solve(L,15)
14
>>> solve(L,17)
17
>>> L.pop(20)
31
>>> solve(L,31)
30
答案 1 :(得分:2)
您可以最快地使用bisect.bisect_left
:
>>> r = range(300)
>>> import bisect
>>> r[bisect.bisect_left(r,280)]
280
这导致算法采用O(log(N))运算(平均),而直线循环平均采用O(N)运算。
要避免该范围顶端的IndexError
,您可以设置hi
关键字:
>>> r[bisect.bisect_right(r,320,hi=len(r)-1)]
299
答案 2 :(得分:2)
>>> max([x for x in [1,3,5,7,9] if x <= 5])
5
答案 3 :(得分:1)
我看到了一个受功能编程启发的答案,但它被删除了,所以我要发布类似的东西:
>>> import functools
>>> L = [1, 3, 15]
>>> x = 10
>>> functools.reduce(lambda a,b: a if b > x else max(a,b), L)
>>> 3
请注意,其他人显示的bisect
解决方案在排序列表上效率更高,但是如果列表未排序,则这与正常for
循环一样高效(或与{{1}}一样高效{3}}),因为复杂性是O(n)。
这个例子仅用于展示python中的一些函数式编程概念。