Python all()/any()类方法,用于列表的一部分?

2024-03-29 12:29:29 发布

您现在位置:Python中文网/ 问答频道 /正文

实现“如果列表中总值的x%大于y,则返回true”的最优雅/python方式是什么。我目前已经实现了一个功能:

def check(listItems, val):
   '''A method to check all elements of a list against a given value.
   Returns true if all items of list are greater than value.'''
   return all(x>val for x in listItems)

但是对于我的用例来说,等待这个特殊的条件是非常昂贵的,而且有些无用。如果列表中约80%的项大于给定值,则我希望继续。 我想到的一种方法是按降序排列列表,创建另一个列表并将列表中80%的元素复制到新列表中,然后为新列表运行函数。然而,我希望一定有一个更优雅的方式来做到这一点。有什么建议吗?你知道吗


Tags: ofto功能true列表valuedefcheck
3条回答

这个呢:

def check(listItems, val, threshold=0.8):
    return sum(x > val for x in listItems) > len(listItems) * threshold

它指出:checkTrue,如果listItems中超过threshold%(默认值为0.80)的元素大于val。你知道吗

这听起来像是你在处理长名单,这就是为什么这是昂贵的。如果你能在符合条件的情况下尽早退出就好了。any()将执行此操作,但您希望避免在传递给any()之前读取整个列表。一个选项可能是使用itertools.accumulate来保持True值的运行总数,并将其传递给任何一个值。比如:

from itertools import accumulate

a = [1, 2, 2, 3, 4, 2, 4, 1, 1, 1]

# true if 50% are greater than 1
goal = .5 * len(a) # at least 5 out of 10   
any( x > goal for x in accumulate(n > 1 for n in a))

accumulate不需要读取整个列表-它只会开始传递到该点所看到的真值的数量。any应该在找到一个真值后立即短路,在上面的例子中,这个真值位于索引5处。你知道吗

你可以用filter来做这个。到目前为止,这是最快的方法。请参考我的另一个答案,因为这比其中的方法快。你知道吗

def check(listItems, val, goal=0.8):
    return len((*filter(val.__lt__, listItems),)) >= len(listItems) * goal

我的另一个问题中的测试结果是:

1.684135717988247

相关问题 更多 >