支持过滤的数组生成器通过在yield前嵌入条件判断实现边生成边筛选,接受predicate函数、集合或区间等多类型过滤条件,兼顾惰性求值与内存效率。

要编写一个支持过滤的数组生成器,核心是让生成器既能按需产出数据,又能在产出前对每个元素做条件判断。关键不是先生成再过滤,而是边生成边筛选,避免浪费内存和计算资源。
用生成器函数 + 条件判断实现
Python 中最直接的方式是定义生成器函数,在 yield 前加入过滤逻辑。比如生成 1 到 100 中所有偶数:
- 定义函数时接受一个可选的
predicate(谓词函数),默认为恒真函数lambda x: True - 循环中对每个候选值调用
predicate(value),仅当返回True时才yield - 这样既保持惰性求值,又把过滤逻辑解耦、可复用
支持多种过滤方式的灵活设计
实际使用中,过滤条件常不止一种。可以支持传入函数、可迭代对象(如黑名单)、或简单类型(如指定数值范围):
- 传入函数:如
lambda x: x % 3 == 0表示只产出 3 的倍数 - 传入集合或列表:如
exclude={5, 10, 15},跳过这些值 - 传入元组表示区间:
range_filter=(10, 50),只产出 10 ≤ x - 内部统一转换为布尔函数,保持
yield处逻辑一致
与内置工具组合提升实用性
不必重复造轮子,可结合 itertools 和生成器表达式增强能力:
- 用
itertools.count()或itertools.cycle()作底层数据源,适配无限序列 - 用
filter()包裹你的生成器,实现链式过滤(注意:filter本身也是惰性的) - 生成器表达式
(x for x in source if condition(x))是简洁替代,适合简单场景 - 若需状态(如“跳过前 N 个”),在生成器函数内维护局部变量,比纯表达式更清晰
注意边界与调试友好性
生成器看不见中间结果,调试时容易困惑。建议:
- 给生成器加参数如
debug=False,开启时打印被跳过的值(仅用于开发) - 明确文档说明:过滤发生在 yield 前,不会改变原始序列顺序
- 避免在 predicate 中做副作用操作(如修改外部变量),保持纯函数特性
- 对空输入或无效 predicate 提前校验,抛出清晰异常而非静默失败











