El módulo operator expone funciones eficientes equivalentes a los operadores intrínsecos de Python. operator.add(a, b) realiza la misma operación que a + b, mientras que operator.getitem(obj, clave) corresponde a obj[clave]. Herramientas como itemgetter(), attrgetter() y methodcaller() crean callables reutilizables para ordenación, agrupamiento, mapeo, callbacks y tablas de comportamiento.
El objetivo no es sustituir la sintaxis normal. En una expresión directa, a + b es más claro. El módulo destaca cuando una API espera una función, como sorted(), map(), reduce() o itertools.groupby().
Operadores aritméticos como funciones
import operator
print(operator.add(10, 5))
print(operator.sub(10, 5))
print(operator.mul(10, 5))
print(operator.truediv(10, 5))
print(operator.pow(2, 8))Estas funciones respetan los métodos especiales del objeto. add() puede sumar números, concatenar secuencias o invocar un __add__() personalizado.
Usar operator con reduce
from functools import reduce
from operator import mul
producto = reduce(mul, [2, 3, 4], 1)
print(producto)Para sumas simples, prefiere sum(). Usa reduce() cuando la operación y la identidad estén claras y el resultado siga siendo legible.
Comparaciones como callables
lt, le, eq, ne, ge y gt implementan comparaciones ricas.
comparadores = {
"menor": operator.lt,
"igual": operator.eq,
"mayor": operator.gt,
}
resultado = comparadores["mayor"](10, 3)Objetos personalizados pueden devolver valores que no son booleanos estrictos. Convierte con bool() cuando el consumidor exija un valor lógico real.
Identidad y None
is_() e is_not() comprueban identidad. Python 3.14 añadió is_none() e is_not_none(), útiles en filtros.
from operator import is_not_none
valores = [10, None, 20, None, 30]
validos = list(filter(is_not_none, valores))Identidad no es igualdad. Usa identidad para sentinelas como None y eq() para valores.
Pruebas de verdad
truth(obj) equivale a bool(obj) y not_(obj) a not obj.
activos = list(filter(operator.truth, [0, 1, "", "ok", [], [1]]))Esto elimina cero, colecciones vacías, cadenas vacías y None al mismo tiempo. No lo uses cuando cero o vacío sean valores válidos.
itemgetter para mappings y secuencias
itemgetter() crea una función que invoca __getitem__(). Se usa mucho como clave de ordenación.
from operator import itemgetter
productos = [
{"nombre": "A", "precio": 30},
{"nombre": "B", "precio": 10},
{"nombre": "C", "precio": 20},
]
ordenados = sorted(productos, key=itemgetter("precio"))Varios elementos producen una tupla y permiten ordenar por múltiples campos.
clave = itemgetter("categoria", "precio")Slices con itemgetter
El argumento puede ser cualquier clave admitida por el objeto, incluso un slice.
ultimos = itemgetter(slice(-3, None))
print(ultimos([1, 2, 3, 4, 5]))Es elegante en pipelines pequeños. Usa una función nombrada cuando necesites validación, documentación o fallback.
attrgetter para atributos
attrgetter() recupera uno o varios atributos y acepta rutas con puntos.
from operator import attrgetter
usuarios_ordenados = sorted(usuarios, key=attrgetter("perfil.nombre"))Si falta un atributo, se propaga la excepción normal. Escribe una función explícita cuando los valores opcionales requieran un valor por defecto.
methodcaller para llamar métodos
methodcaller() crea una función que invoca un método con argumentos fijos.
from operator import methodcaller
nombres = [" Ana ", " BRUNO", "carla "]
limpios = list(map(methodcaller("strip"), nombres))
minusculas = list(map(methodcaller("lower"), limpios))No permitas nombres de métodos arbitrarios proporcionados por usuarios sin una lista estricta.
operator.call
Desde Python 3.11, call(obj, *args, **kwargs) invoca un callable.
tareas = [lambda: "A", lambda: "B"]
resultados = list(map(operator.call, tareas))La sintaxis directa es más clara en código normal. call() sirve cuando el acto de llamar debe pasarse como función.
Operaciones de secuencia
contains(a, b) ejecuta b in a; observa el orden invertido. countOf(), indexOf() y concat() ofrecen otras operaciones.
print(operator.contains([1, 2, 3], 2))
print(operator.countOf("banana", "a"))
print(operator.indexOf([10, 20, 30], 20))El orden de argumentos de contains() es una fuente frecuente de errores.
getitem, setitem y delitem
datos = {"activo": False}
operator.setitem(datos, "activo", True)
print(operator.getitem(datos, "activo"))
operator.delitem(datos, "activo")Estas funciones ayudan en tablas genéricas. La sintaxis directa sigue siendo preferible cuando la clave es conocida.
length_hint
length_hint() intenta obtener la longitud real o una estimación de un iterable.
iterador = iter(range(100))
estimacion = operator.length_hint(iterador)El resultado es solo una pista para preasignación. Nunca lo uses como conteo confiable ni límite de seguridad.
Bits y matrices
El módulo incluye and_(), or_(), xor(), invert(), desplazamientos y matmul(). El guion bajo evita conflictos con palabras reservadas.
Estas funciones invocan los mismos métodos especiales que la sintaxis y pueden operar con sets, arrays y objetos numéricos.
Operaciones in-place
iadd(), imul() y funciones relacionadas llaman métodos in-place. Los objetos mutables pueden cambiar. Los inmutables producen un nuevo valor, pero la variable del llamador no se reasigna automáticamente.
texto = "Hola"
nuevo = operator.iadd(texto, " mundo")
print(texto) # sin cambios
lista = [1, 2]
operator.iadd(lista, [3])
print(lista) # modificadaConserva siempre el valor devuelto en código genérico cuando no conozcas la mutabilidad.
Tabla segura de operaciones
OPERACIONES = {
"+": operator.add,
"-": operator.sub,
"*": operator.mul,
"/": operator.truediv,
}
def calcular(a, simbolo, b):
try:
funcion = OPERACIONES[simbolo]
except KeyError:
raise ValueError("operación no permitida")
return funcion(a, b)Una lista permitida es más segura que eval(). Aun así, valida tipos, división por cero, límites y coste de la operación.
Rendimiento y legibilidad
itemgetter() y attrgetter() son eficientes, pero su ventaja sobre lambdas rara vez debe ser la primera preocupación. Elige la forma que mejor comunique la regla.
Una lambda o función nombrada es mejor cuando la clave necesita transformación, valores por defecto o manejo de errores.
Errores frecuentes
- Usar el módulo donde la sintaxis directa es más clara.
- Invertir los argumentos de
contains(). - Confundir identidad con igualdad.
- Descartar el retorno in-place de un objeto inmutable.
- Filtrar con
truth()cuando cero es válido. - Usar getters con campos opcionales sin tratamiento.
- Usar
eval()en vez de una tabla permitida.
Buenas prácticas
- Usa getters para ordenar y agrupar.
- Usa funciones nombradas cuando exista lógica.
- Autoriza explícitamente operaciones de usuarios.
- Conserva el retorno de funciones in-place.
- Usa identidad solo para sentinelas.
- Prueba objetos personalizados y excepciones.
- Prioriza claridad sobre microoptimización.
Guías relacionadas
Continúa con bisect en Python, statistics en Python, fractions en Python, Decimal en Python e inspect en Python.
Consulta la documentación oficial de operator y la documentación de functools.
Conclusión
El módulo operator convierte operaciones del lenguaje en valores callables, simplificando ordenaciones, agrupamientos, mapeos y tablas de comportamiento. Es más útil en APIs funcionales; para expresiones normales, la sintaxis nativa sigue siendo la opción más clara.







