【问题标题】:Check if values in list exceed threshold a certain amount of times and return index of first exceedance检查列表中的值是否超过阈值一定次数并返回第一次超出的索引
【发布时间】:2017-01-10 16:44:44
【问题描述】:

我正在寻找一种简洁的 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]

【问题讨论】:

  • 示例 1 未通过您的第二个阈值。正好有 5 个数字 >4
  • @Chris_Rands 我认为他的门槛是包容性的
  • 我也注意到了,OP 交替使用 'exceeded' 和 'reached' 所以很难猜出他想要什么。
  • @Chris_Rands 阈值可以大于等于或大于,这并不重要,抱歉对这个事实含糊不清。明天将仔细查看代码答案!已经要感谢大家的精彩回答!

标签: python list iterator threshold


【解决方案1】:
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

【讨论】:

  • 不错的一个!对不起
【解决方案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 在 cmets 中提到的,return None 是不必要的。删除它不会改变函数的结果。

【讨论】:

  • return testlist.index(overages[0])
  • @Ev.Kounis 啊,是的,谢谢。错过了问题的索引部分。
  • return None 是不必要的,Python 会return None 反正
  • @Chris_Rands 没错,但它让 OP 清楚地知道发生了什么。而且它不花钱,所以我觉得还是不错的。
【解决方案3】:

我不知道我是否会称它为 clean 或 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】:

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

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

    【讨论】:

    • 简短、简单、快速!感谢您的贡献!会以此为依据! (感谢所有其他人,他们都工作得很好!)
    【解决方案5】:

    一种简单直接的方法是遍历列表,计算大于第一个阈值的项目数,如果计数超过第二个阈值,则返回第一个匹配项的索引:

    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 是输入列表中的项目总数。

    【讨论】:

      【解决方案6】:

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

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-03-23
        • 1970-01-01
        • 2015-08-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多