operator模块提供c实现的运算符函数,比lambda快15–25%,用于map/filter/sorted/reduce等场景,支持算术、比较、属性/项访问(如itemgetter、attrgetter),但不处理异常或提供默认值。

operator 模块本身不提升运行速度,它只是让高阶函数调用更简洁、更安全——但间接减少开销,尤其在 map、filter、sorted 和 functools.reduce 中避免了 lambda 创建和解释执行的额外成本。
为什么用 operator.add 代替 lambda x, y: x + y?
每次写 lambda x, y: x + y,Python 都要动态构建一个函数对象,涉及 AST 解析、字节码生成和闭包封装。而 operator.add 是 C 实现的内置函数,直接调用底层二元操作,没有解释层开销。
-
functools.reduce(lambda a, b: a + b, data)→functools.reduce(operator.add, data) - 在循环密集或数据量大的场景(如百万级 list reduce),实测快 15–25%
- 注意:
operator.add要求所有元素支持+,比如不能混用str和int,否则抛出TypeError
operator.itemgetter 和 operator.attrgetter 在 sorted 中的实际表现
它们比等效的 lambda 更快,且更易读、更少出错。关键在于:它们被设计为单次编译、多次复用,而 lambda 每次调用都走一遍函数调用协议。
-
sorted(data, key=lambda x: x['name'])→sorted(data, key=operator.itemgetter('name')) -
sorted(people, key=lambda p: p.age)→sorted(people, key=operator.attrgetter('age')) - 当
key函数被反复调用(如排序时比较数万次),itemgetter的 C 层索引逻辑明显优于 Python 层字典/属性访问 - 支持多字段:
operator.itemgetter('first', 'last')返回 tuple,天然适配稳定排序的次要键
哪些操作符有对应函数?哪些没有?
operator 模块覆盖了绝大多数常见双目/单目运算,但不是全部;用错名字会直接报 NameError 或 AttributeError。
- 有:
operator.eq、operator.lt、operator.mul、operator.neg、operator.not_(注意下划线)、operator.contains - 没有:
**(幂)对应的是operator.pow,不是operator.pow_;is没有对应函数(只能用operator.is_—— 对,就是is_) - 字符串方法如
.upper()不在operator中,别试图找operator.upper;要用methodcaller('upper') - 自定义类若重载了
__add__,operator.add仍能正常工作,它本质是触发 dunder 方法的统一入口
真正容易被忽略的是:operator 函数本身不处理异常传播——如果 operator.itemgetter('missing') 遇到 key 不存在,它抛的 KeyError 和你手写的 lambda 一模一样,不会更友好。要不要加默认值,得靠外层逻辑兜底,而不是指望 operator 帮你吞掉错误。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











