filter函数基本用法是接收判断函数和可迭代对象,返回过滤后元素组成的迭代器;其返回值为filter对象(Python 3中的迭代器),非列表,需用list()等显式转换方可多次使用或直接查看。

filter 函数的基本用法和返回值类型
filter 不会直接返回列表,而是返回一个 filter 对象(Python 3 中的迭代器)。如果直接打印或想反复使用结果,必须显式转成 list、tuple 等可遍历容器。
常见错误是写完 filter(lambda x: x > 0, nums) 就以为得到列表,结果在 for 循环里用一次就耗尽,或者打印出来只看到类似 <filter object at 0x...> 的内容。
- 需要立即获取全部结果时,用
list(filter(...)) - 处理大数据流时,保留
filter对象更省内存,配合next()或单次for遍历即可 -
filter第二个参数必须是可迭代对象,传入None或非迭代类型(如整数)会报TypeError: 'int' object is not iterable
lambda 表达式里访问外部变量的坑
当用 lambda 引用循环变量或闭包外的变量时,容易遇到“晚绑定”问题:所有 lambda 实际共享同一个变量引用,最终取值是循环结束后的值。
例如下面代码本意是生成多个过滤函数,每个对应不同阈值,但实际全按最后一个 thresh 执行:
立即学习“Python免费学习笔记(深入)”;
thresholds = [10, 20, 30] filters = [lambda x: x > thresh for thresh in thresholds]
修复方式是把当前值作为默认参数绑定进去:
filters = [lambda x, t=thresh: x > t for thresh in thresholds]
- 不要在 lambda 内直接引用会变化的外部变量名
- 若逻辑复杂,优先写普通函数代替 lambda,可读性和调试性更好
- lambda 只适合单表达式、无副作用的简单判断
filter + lambda 处理 None 和空值的典型场景
常见需求是过滤掉 None、空字符串、空列表等“falsy”值。但要注意:filter(None, iterable) 是快捷写法,它调用对象的布尔值判断,而 lambda x: x 行为一致;但如果你只想过滤 None 却保留 0、False、'',就不能用 None 作第一个参数。
- 过滤所有 falsy 值(包括
0、False、''、[]):用filter(None, data) - 只过滤
None,保留其他 falsy 值:用filter(lambda x: x is not None, data) - 过滤空字符串但保留
None:用filter(lambda x: x != '', data),注意None != ''是True,所以None会留下
性能与可读性的权衡:什么时候不该用 filter + lambda
对小数据量,filter + lambda 没问题;但一旦条件变复杂(比如要检查嵌套字段、调用多个方法、含异常处理),硬塞进 lambda 会让代码难读且无法调试。
- 涉及属性访问(如
obj.name)、方法调用(如s.strip())、类型检查(如isinstance(x, str))时,建议改用列表推导式:[x for x in data if x and hasattr(x, 'name') and x.name] - 需要提前中断或记录日志?
filter不支持,得手写循环 - 多条件组合时,
lambda x: cond1(x) and cond2(x) and not cond3(x)已经比等价的推导式更难扫一眼看懂
真正关键的不是“能不能用”,而是“改天别人(或你自己)再看这段代码时,能不能不查文档就明白它在筛什么”。lambda 的匿名性在这里是双刃剑。



















