在Python中,如何找到排序列表中第一个大于阈值的值的索引?

发布于 2024-12-02 18:20:58 字数 153 浏览 1 评论 0原文

在Python中,如何找到排序列表中第一个大于阈值的值的索引?

我可以想到几种方法来做到这一点(线性搜索,手写二分法,..),但我正在寻找一种干净且相当有效的方法来做到这一点。由于这可能是一个非常常见的问题,我相信经验丰富的 SOers 可以提供帮助!

谢谢!

In Python, how do you find the index of the first value greater than a threshold in a sorted list?

I can think of several ways of doing this (linear search, hand-written dichotomy,..), but I'm looking for a clean an reasonably efficient way of doing it. Since it's probably a pretty common problem, I'm sure experienced SOers can help!

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦一生花开无言 2024-12-09 18:20:58

看看bisect

import bisect

l = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

bisect.bisect(l, 55) # returns 7

与线性搜索比较:

timeit bisect.bisect(l, 55)
# 375ns


timeit next((i for i,n in enumerate(l) if n > 55), len(l))
# 2.24us


timeit next((l.index(n) for n in l if n > 55), len(l))
# 1.93us

Have a look at bisect.

import bisect

l = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

bisect.bisect(l, 55) # returns 7

Compare it with linear search:

timeit bisect.bisect(l, 55)
# 375ns


timeit next((i for i,n in enumerate(l) if n > 55), len(l))
# 2.24us


timeit next((l.index(n) for n in l if n > 55), len(l))
# 1.93us
街道布景 2024-12-09 18:20:58

您可能会比使用 itertools 的枚举/生成器方法获得更好的时间;我认为 itertools 为我们所有人的性能贩子提供了底层算法的更快实现。但 bisect 可能仍然更快。

from itertools import islice, dropwhile

threshold = 5
seq = [1,4,6,9,11]
first_val = islice(dropwhile(lambda x: x<=threshold, seq),0,1)
result = seq.index(first_val)

我想知道此处显示的二等分方法与文档示例中为您的问题列出的方法之间的区别,就习惯用法/速度而言。他们展示了一种查找值的方法,但截断到第一行,它返回索引。我猜想,由于它被称为“bisect_right”而不是“bisect”,所以它可能只从一个方向看。鉴于您的列表已排序并且您想要大于,这可能是最大的搜索经济。

from bisect import bisect_right

def find_gt(a, x):
    'Find leftmost value(switching this to index) greater than x'
    return bisect_right(a, x)

有趣的问题。

You might get a better time than the enumerate/generator approach using itertools; I think itertools provides faster implementations of the underlying algorithms, for the performance mongers in all of us. But bisect may still be faster.

from itertools import islice, dropwhile

threshold = 5
seq = [1,4,6,9,11]
first_val = islice(dropwhile(lambda x: x<=threshold, seq),0,1)
result = seq.index(first_val)

I wonder about the difference between the bisect approach shown here and the one listed for your question in the doc examples, as far as idiom/speed. They show an approach for finding the value, but truncated to first line, it returns the index. I'd guess that since it's called "bisect_right" instead of "bisect," it probably only looks from one direction. Given that your list is sorted and you want greater-than, this might be the greatest search economy.

from bisect import bisect_right

def find_gt(a, x):
    'Find leftmost value(switching this to index) greater than x'
    return bisect_right(a, x)

Interesting question.

萌无敌 2024-12-09 18:20:58

最后一个大于阈值的元素的相关索引和Val

l = [1, 4, 9, 16, 25, 36, 49, 64, 100, 81, 100]
max((x,i) for i, x in enumerate(l) if x > 4)
(100, 10)

Related Index and Val of the last element greater than a threshold

l = [1, 4, 9, 16, 25, 36, 49, 64, 100, 81, 100]
max((x,i) for i, x in enumerate(l) if x > 4)
(100, 10)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文