Python 函数的搜索算法
给定一个输入列表(假设它们只是整数)和一个函数列表(这些函数接受一个整数,并返回True或False)Python 函数的搜索算法,python,algorithm,Python,Algorithm,给定一个输入列表(假设它们只是整数)和一个函数列表(这些函数接受一个整数,并返回True或False) 我必须获取这个输入列表,看看列表中的任何函数是否会为列表中的任何值返回True 有没有比O(n^2)更快的方法 现在我所拥有的是 for v in values: for f in functions: if f(v): # do something to v break 任何更快的方法?如果没有关于函数的任何进一步信息
我必须获取这个输入列表,看看列表中的任何函数是否会为列表中的任何值返回True 有没有比O(n^2)更快的方法 现在我所拥有的是
for v in values:
for f in functions:
if f(v):
# do something to v
break
任何更快的方法?如果没有关于函数的任何进一步信息,则必须将
len(函数)*len(值)
可能的函数调用的结果视为彼此独立,因此没有比检查所有函数调用更快的方法了
不过,您可以写得更简洁一些:
any(f(v) for v in values for f in functions)
内置函数any()
也会短路,就像原始代码一样
编辑:结果表明,所需的等效项
all(any(f(v) for f in functions) for v in values)
请参阅评论进行讨论。不,没有更快的方法。O(m*n)是极限。如果你有更多关于函数的信息,你也许能够克服这一点,但在一般情况下,没有。如果你知道更多关于函数或值的信息,你可以做常规搜索引擎所做的事情——对值列表应用某种索引,只需要一次遍历 编辑: 下面是一种使用
any()
的方法,适用于此用例
for v in values:
if any(f(v) for f in functions):
#do something to v
如果只查询它们,而不对手头的函数进行一些简化假设,那么就没有比
O(nm)
更好的了
这是因为证明不存在任何此类函数需要证明,对于任何整数和任何函数,查询结果都是False
为了证明这一点,你只能执行所有的查询,因为你的是O(2^nm)
,而一个查询只是状态空间的一半,所以你需要O(log_2(2^nm))=O(nm)
查询来将你的状态空间减少到“每个函数对每个整数都返回false”的解,但它可以避免您每次迭代函数:
#combine all funcs into one with `or`
newFunc = reduce(lambda f,g: (lambda x: f(x) or g(x)), funcs)
#cleaner than for, i think
satisfied = any(map(newFunc, values))
讨论嵌套lambda是否是pythonic完全是另一回事,但在处理函数列表时,我倾向于从函数的角度来考虑。我希望函数是纯函数?您还知道关于它们的其他信息吗?“对于列表中的任何值都返回True”。。。这是否意味着函数对每个值都返回true。。。或者只是任何一个值?这可能会更快,因为
any(f(v)表示函数中f的值中v的值)
,但不少于O(n_函数*n_值)时间。有趣的想法。注意Python(2.7)中的any()
是一个全局内置的,不是list的类方法。@KarolyHorvath不,不幸的是(该死的严格性…)如果我有更多的时间,我会想到一些延迟或的结构。但是你可能又会有更多的开销——可能和列表差不多。这是一个恶性循环。如果你能想出一个优雅的解决方案,我真的很感兴趣。