Python 过滤并结构化数据,前面3个例子都是将数据处理和映射相结合,过滤并处理数据相比而言不那么明了,下面举例说明过滤并处理这对组合虽然很有用,但是其应用场景不如处理并映射这对组合典型。
前面介绍过,借助结构化数据算法,可以方便地将带有结构化算法的过滤器与一个复杂函数结合起来。从可迭代对象中取出部分值的函数如下:
from typing import Iterator, Tuple
def group_by_iter(n: int, items: Iterator) -> Iterator[Tuple]:
row = tuple(next(items) for i in range(n))
while row:
yield row
row = tuple(next(items) for i in range(n))
该函数从一个可迭代对象中取出 n 个元素,输入可迭代对象中的元素作为输出结果的一部分依次被yield
语句返回。原则上,该函数递归处理输入可迭代对象中的值,但由于递归在Python中效率较低,这里用显式的while
循环代替递归。
如下所示使用该函数:
group_by_iter(7,
filter(lambda x: x % 3 == 0 or x % 5 == 0, range(100))
)
首先使用range()
函数创建一个可迭代对象,然后用filter
函数进行过滤,最后进行分组。
将分组和过滤放在同一个函数体中,就实现了一个函数包含分组和过滤两个处理步骤,修改后的函数如下所示:
def group_filter_iter(
n: int, pred: Callable, items: Iterator) -> Iterator:
subset = filter(pred, items)
row = tuple(next(subset) for i in range(n))
while row:
yield row
row = tuple(next(subset) for i in range(n))
首先使用谓词函数处理输入可迭代对象,生成一个非严格的可迭代对象,所以不会立刻对data
变量求值,而只在需要的时候才求值,这个函数的实现方法与前面的例子一样。
略微简化一下上下文,如下所示使用该函数:
group_filter_iter(
7,
lambda x: x % 3 == 0 or x % 5 == 0,
range(1, 100)
)
只需一次函数调用,就可以过滤并提取数据。但将filter()
函数和其他处理步骤放在一起往往不够清晰,大多数情况下,单独的filter()
函数比组合函数更实用。