gpt4 book ai didi

python - 将多个过滤器应用于元组列表

转载 作者:IT老高 更新时间:2023-10-28 20:56:35 25 4
gpt4 key购买 nike

我正在寻找一种高效的 Pythonic 方式来将多个过滤器应用于元组列表。

例如,假设过滤器是这样的:

def f1(t): return t[3]<10
def f2(t): return t[0]!=1
def f3(t): return t[1] in ("lisa","eric")
def f4(t): return t[3]>2

和这样的 n 元组(即 db-records):

tuples=[
(0,'tom','...',8),
(1,'john','...',17),
(2,'lisa','...',1),
(3,'eric','...',18)
]

以下作品:

def nFilter(filters,tuples):
if filters and tuples:
return nFilter(filters,filter(filters.pop(),tuples))
else: return tuples

结果如下:

>>> nFilter([f1,f2,f3],tuples)
[(2, 'lisa', '...', 1)]

>>> nFilter([f1,f2,f3,f4],tuples)
[]

但我想知道是否有更直接的方法;我想到的是函数组合(即 f1(f2(...fn(tuples)...))),用于任意函数列表。有对 functional library 的引用在文档中包含 compose 函数,但链接都已失效。

另外,由于我计划在相当大的数据集上使用它,并且可能在生产 Web 服务中使用大量过滤器,它必须是高效的,我真的不能说这个解决方案是否有效。

欢迎提出任何建议或改进。

最佳答案

改进:用迭代代替递归

实际上并没有“用于任意函数列表的组合函数”;但是,使用简单的 for 循环构建过滤器链非常容易:

def nFilter(filters, tuples):
for f in filters:
tuples = filter(f, tuples)
return tuples

改进:按限制和速度排序过滤器

链式迭代器的速度如此之快,以至于总运行时间往往会被对谓词函数的调用所支配。

通过对谓词进行排序以最小化总工作可以获得最佳结果。一般来说,最好将廉价的测试放在昂贵的测试之前,并将限制性更强的测试放在不能过滤掉很多情况的测试之前。

示例

在此示例中,谓词的成本大致相同(函数调用、元组索引和与常量的比较),但它们的限制不同(t[2]==4 过滤掉了 80% 的情况,而 t[0]>1t[1]<3每个只过滤掉 40% 的数据)。

>>> from itertools import product

>>> filters = [lambda t: t[2]==4, lambda t: t[0]>1, lambda t: t[1]<3]
>>> for tup in nFilter(filters, product(range(5), repeat=3)):
print(tup)

(2, 0, 4)
(2, 1, 4)
(2, 2, 4)
(3, 0, 4)
(3, 1, 4)
(3, 2, 4)
(4, 0, 4)
(4, 1, 4)
(4, 2, 4)

从评论中提取的注释

  • 当输入迭代为空时,过滤器函数对谓词的应用为零。这就像在一个空列表上做一个 for 循环。

  • 每个过滤器都会减少输入封闭过滤器的数据量。因此,每个过滤器只会应用于通过之前过滤器的数据。

  • 不用担心示例中的 lambda。它具有与常规 def 相同的功能。这只是编写过滤器列表的一种便捷方式。

  • 在 Python 3 中,更新了 filter() 函数以返回迭代器而不是列表。在 Python 2 中,您可以使用 itertools.ifilter() 而不是 filter() 来实现相同的效果。

关于python - 将多个过滤器应用于元组列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12386199/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com