检查列表中的值是否超过阈值一定次数并返回第一次超出的索引

时间:2016-09-02 14:15:45

标签: python list iterator threshold

我正在寻找一种干净和pythonic的方法来检查列表的内容是否大于给定数量(第一个阈值)一定次数(第二个阈值)。如果两个语句都为真,我想返回超过给定阈值的第一个值的索引。

示例

# Set first and second threshold
thr1 = 4
thr2 = 5

# Example 1: Both thresholds exceeded, looking for index (3)
list1 = [1, 1, 1, 5, 1, 6, 7, 3, 6, 8]

# Example 2: Only threshold 1 is exceeded, no index return needed
list2 = [1, 1, 6, 1, 1, 1, 2, 1, 1, 1]

6 个答案:

答案 0 :(得分:3)

我不知道是否被认为是pythonic滥用布尔值的事实,但我喜欢这样做

def check(l, thr1, thr2):
    c = [n > thr1 for n in l]
    if sum(c) >= thr2:
        return c.index(1)

答案 1 :(得分:2)

试试这个:

def check_list(testlist)
    overages = [x for x in testlist if x > thr1]
    if len(overages) >= thr2:
        return testlist.index(overages[0])
    # This return is not needed. Removing it will not change
    # the outcome of the function.
    return None

这使用了以下事实:您可以使用列表推导中的if语句来忽略非重要值。

如评论中Chris_Rands所述,return None是不必要的。删除它不会改变函数的结果。

答案 2 :(得分:0)

一种天真而直接的方法是迭代列表,计算大于第一个阈值的项目数,如果计数超过第二个阈值则返回第一个匹配的索引:

def answer(l, thr1, thr2):
    count = 0
    first_index = None
    for index, item in enumerate(l):
        if item > thr1:
            count += 1
            if not first_index:
                first_index = index

            if count >= thr2:  # TODO: check if ">" is required instead
                return first_index

thr1 = 4
thr2 = 5

list1 = [1, 1, 1, 5, 1, 6, 7, 3, 6, 8]
list2 = [1, 1, 6, 1, 1, 1, 2, 1, 1, 1]

print(answer(list1, thr1, thr2))  # prints 3
print(answer(list2, thr1, thr2))  # prints None

这可能不是pythonic,但是这个解决方案有几个优点 - 我们只保留第一个匹配的索引并且提前退出循环如果我们达到第二个门槛。

换句话说,我们在最佳情况下O(k),在最坏情况下O(n),其中k是达到第二个阈值之前的项目数; n是输入列表中的项目总数。

答案 3 :(得分:0)

我不知道我是否称它为干净或pythonic,但这应该有效

def get_index(list1, thr1, thr2):
    cnt = 0
    first_element = 0
    for i in list1:
        if i > thr1:
            cnt += 1
            if first_element == 0:
                first_element = i

    if cnt > thr2:
        return list1.index(first_element)
    else:
        return "criteria not met"

答案 4 :(得分:0)

thr1 = 4
thr2 = 5
list1 = [1, 1, 1, 5, 1, 6, 7, 3, 6, 8]
list2 = [1, 1, 6, 1, 1, 1, 2, 1, 1, 1]

def func(lst)
    res = [ i for i,j in enumerate(lst) if j > thr1]
    return len(res)>=thr2 and res[0]

输出:

func(list1)
3
func(list2)
false

答案 5 :(得分:0)

如果您正在寻找单行(或几乎)

a = filter(lambda z: z is not None, map(lambda (i, elem) : i if elem>=thr1 else None, enumerate(list1))) 
print a[0] if len(a) >= thr2 else false