Funciones Lambda de Python: Sintaxis, usos reales y cuándo no utilizarlos
Una lambda es una función pequeña que puedes escribir en una línea, justo donde la necesitas. Aprenda la sintaxis, los lugares en los que las lambdas realmente ayudan, la trampa que atrapa a los desarrolladores experimentados y cuándo una función normal es simplemente mejor.
- Una lambda es una función anónima limitada a una sola expresión.
- Su mejor uso es como argumento breve, especialmente el
keyparasorted,minymax. - La comprensión de una lista suele ser más clara que
mapofiltercon una lambda. - Si asigna una lambda a un nombre, escriba
defen su lugar.
Necesita ordenar los productos por precio. Escribir una función con nombre separado solo para decir “usar el precio” parece una gran ceremonia. Funciones lambda de Python te permiten definir esa pequeña pieza de lógica en línea, exactamente dónde la usas.
Las lambdas son útiles, pero también fáciles de usar en exceso. Esta guía muestra dónde realmente ayudan y dónde dificultan la lectura del código. Ejecutamos todos los ejemplos en Python 3.13 y el resultado que se muestra proviene de esa ejecución.
¿Qué es una lambda?
Una lambda es una función sin nombre, escrita con la palabra clave lambda:
lambda arguments: expression
Toma cualquier número de argumentos y devuelve el valor de una sola expresión, automáticamente. No hay return palabra clave ni cuerpo de declaraciones.
square = lambda x: x * x
print(square(4)) # 16
print((lambda a, b=10: a + b)(5)) # 15
La segunda línea define una lambda con un argumento predeterminado y la llama inmediatamente. Raramente escribirías esto en código real, pero muestra que una lambda es un objeto de función común y corriente.
lambda vs def
Estos dos producen funciones que se comportan igual:
square = lambda x: x * x
def square_def(x):
return x * x
print(square(4), square_def(4)) # 16 16
print(square.__name__, square_def.__name__) # <lambda> square_def
Mira los nombres. Cada lambda se llama simplemente <lambda>, por lo que los mensajes de error y los registros no pueden indicar cuál falló. Esta es la razón principal por la que las guías de estilo como PEP 8 recomiendan un def siempre que quieras darle un nombre a una función.
| Característica | lambda |
definición |
|---|---|---|
| Nombre | anónimo | Nombrado |
| cuerpo | una expresión | Cualquier número de declaraciones |
| Regresar | implícito | Explícito return |
| Cadena de documentación y sugerencias de tipo | No compatible | Apoyado |
| Rastreos legibles | Espectáculos <lambda> |
Muestra el nombre |
| Lo mejor para | Argumentos breves y desechables | Todo lo demás |
Ordenar con clave: el mejor uso
Funciones como sorted, min y max aceptan una función key que decide qué comparar. Aquí es donde brillan las lambdas:
products = [("pen", 10), ("bag", 900), ("book", 250)]
sorted(products, key=lambda p: p[1])
# [('pen', 10), ('book', 250), ('bag', 900)]
max(products, key=lambda p: p[1])
# ('bag', 900)
Para ordenar por varias cosas, devuelve una tupla. Aquí, las personas están clasificadas por edad, primero por edad y luego por nombre:
people = [{"name": "Asha", "age": 31}, {"name": "Ben", "age": 25},
{"name": "Dev", "age": 31}]
[p["name"] for p in sorted(people, key=lambda p: (-p["age"], p["name"]))]
# ['Asha', 'Dev', 'Ben']
El signo menos invierte el orden del número únicamente. A veces no se necesita ninguna lambda porque una función existente ya hace el trabajo. Compare el orden predeterminado con uno que no distinga entre mayúsculas y minúsculas:
names = ["Asha", "ben", "Chitra", "dev"]
sorted(names) # ['Asha', 'Chitra', 'ben', 'dev']
sorted(names, key=str.lower) # ['Asha', 'ben', 'Chitra', 'dev']
De forma predeterminada, todas las palabras en mayúscula se colocan primero. Pasar str.lower soluciona eso sin ninguna lambda. El módulo operator ofrece ayudas similares, como itemgetter(1) para lambda p: p[1].
mapa y filtro
map aplica una función a cada elemento y filter mantiene los elementos para los que devuelve verdadero. Ambos funcionan con lambdas, pero comparan cada uno con una lista de comprensión:
nums = [1, 2, 3, 4, 5, 6]
list(map(lambda n: n * 10, nums)) # [10, 20, 30, 40, 50, 60]
[n * 10 for n in nums] # [10, 20, 30, 40, 50, 60]
list(filter(lambda n: n % 2 == 0, nums)) # [2, 4, 6]
[n for n in nums if n % 2 == 0] # [2, 4, 6]
Los resultados son idénticos y la mayoría de los desarrolladores de Python encuentran que la comprensión es más fácil de leer. Observe también que map y filter devuelven iteradores diferidos, por lo que necesita list() para ver los valores. Nuestra guía para la comprensión de listas de Python cubre ese estilo en profundidad. map todavía se lee bien con una función con nombre existente, como en map(str.strip, lines).
reducir
functools.reduce combina elementos en un solo valor y genera un resultado continuo:
from functools import reduce
reduce(lambda acc, n: acc + n, nums, 0) # 21
sum(nums) # 21
Para trabajos comunes, como totales, utilice un integrado como sum, max o any. Mantenga reduce para casos más raros y considere un bucle simple si la lambda comienza a parecer complicada.
Condiciones en una lambda
No puedes usar una declaración if en una lambda, pero puedes usar una expresión condicional:
label = lambda total: "large" if total >= 1000 else "small"
label(1200), label(300)
# ('large', 'small')
Una condición está bien. Una vez que comienzas a anidarlos, los lectores tienen que trabajar duro, lo cual es una señal clara para cambiar a def con declaraciones if ordinarias.
Lambdas que devuelven funciones
Una función puede crear y devolver una lambda que recuerda un valor de su entorno:
def multiplier(n):
return lambda x: x * n
double = multiplier(2)
double(7) # 14
Esto funciona debido a los cierres, que nuestro artículo sobre Cierres de JavaScript explica en un idioma diferente. Python functools.partial ofrece otra forma de precompletar argumentos.
La trampa de la vinculación tardía
Esto acaba por atrapar a casi todo el mundo. Creamos tres lambdas en un bucle, esperando que cada una devolviera su propio número:
funcs = [lambda: i for i in range(3)]
[f() for f in funcs]
# [2, 2, 2]
Los tres devuelven 2. Una lambda no captura el valor de i cuando se crea. Busca la variable cuando se llama, y para entonces el ciclo ha terminado, dejando i en 2. La solución habitual es capturar el valor como argumento predeterminado, ya que los valores predeterminados se evalúan en el momento de la definición:
funcs = [lambda i=i: i for i in range(3)]
[f() for f in funcs]
# [0, 1, 2]
Esto no es exclusivo de las lambdas, ya que def dentro de un bucle se comporta de la misma manera. Simplemente aparece con más frecuencia con lambdas, porque comúnmente se crean en bucles, como cuando se adjuntan devoluciones de llamada de botones.
Consejo: Si necesita una función por elemento, considere si necesita muchas funciones. A menudo, una única función que toma el elemento como argumento es más clara y evita la trampa por completo.
Tablas de búsqueda de funciones pequeñas.
Lambdas encaja perfectamente en un diccionario que asigna nombres a operaciones pequeñas:
ops = {
"add": lambda a, b: a + b,
"sub": lambda a, b: a - b,
}
ops["sub"](10, 3) # 7
Esto puede reemplazar una larga cadena de if y elif. La guía Diccionario de Python cubre más patrones de diccionario y el módulo operator ya proporciona operator.add y operator.sub.
Límites de lambdas
- Solo una expresión. Sin asignaciones con
=, sin bucles y sin bloquestry. - Sin declaraciones. Escribir
lambda x: return xfalla con unSyntaxError, como confirmó nuestra prueba. - Sin cadenas de documentación ni sugerencias de tipo. Las herramientas y los lectores reciben menos ayuda.
- Depuración más complicada. Los errores apuntan a
<lambda>en lugar de a un nombre útil.
Por supuesto, Lambdas aún puede generar excepciones. Manejarlos funciona igual que para cualquier función, como se explica en Manejo de excepciones de Python.
Cuando no usar una lambda
| Situación | Mejor elección |
|---|---|
| Asignándole un nombre | definición |
| La lógica necesita más de una línea. | definición |
| Transformar o filtrar una lista | Una lista de comprensión |
| Sumar o encontrar un máximo | sum, max, min |
| Obtener un artículo o atributo | operator.itemgetter o attrgetter |
| La misma lambda aparece en varios lugares. | Una función con nombre que puedes probar |
Ese último punto importa. Vale la pena probar la lógica que vale la pena reutilizar, y una función con nombre es mucho más fácil de probar, como muestra nuestro tutorial de pytest.
Conclusión
Una buena lambda es lo suficientemente corta como para leerla de un vistazo y usarse una vez, generalmente como argumento. Las claves de clasificación son el ejemplo clásico. Para verificar su propio código, busque = lambda y conviértalo en funciones con nombre. Luego mire cualquier map o filter con una lambda y vea si la comprensión se lee mejor.
Preguntas frecuentes
¿Qué es una función lambda en Python?
Es una pequeña función anónima creada con la palabra clave lambda. Toma argumentos y devuelve el valor de una sola expresión, sin nombre ni declaración de retorno.
¿Puede una lambda de Python tener varias líneas?
No. Una lambda está limitada a una expresión. Puede dividirlo en líneas entre paréntesis, pero aún así no puede contener declaraciones, así que use def para una lógica más compleja.
¿Puedo usar if else en una lambda?
Puede utilizar una expresión condicional, como lambda x: “grande” si x > 10 o “pequeño”. No se permite una declaración if con un bloque.
¿Son las lambdas más rápidas que las funciones normales?
No de manera significativa. Ambos crean el mismo tipo de objeto de función. Elija entre ellos por legibilidad, no por rendimiento.
¿Debo usar un mapa con lambda o una lista de comprensión?
La mayoría de los desarrolladores de Python prefieren una lista de comprensión para facilitar la lectura. map es razonable cuando ya tiene una función con nombre, como map(str.strip, líneas).
sigue aprendiendo
¿Necesitas ayuda con pruebas, WordPress o SEO?
Ayudamos a los equipos a enviar mejor software y hacer crecer sus sitios. Cuéntenos en qué está trabajando y le sugeriremos un siguiente paso claro.
Más guías sobre testing, IA y desarrollo moderno
¿Te gustó este artículo? Elige un tema y salta directo a nuestros tutoriales más recientes.
Explicación de las alucinaciones de la IA: por qué los modelos de lenguaje inventan cosas y cómo reducirlas
Se explicaron las alucinaciones de la IA: qué son, por qué los modelos de lenguaje las producen, tipos comunes, cómo reducirlas con conexión a tierr…
Leer artículo →DevOpsExplicación de las variables de entorno: archivos .env, secretos y configuración bien hechos
Variables de entorno explicadas con ejemplos de Python que ejecutamos: leerlas y configurarlas, por qué cada valor es una cadena, archivos .env, her…
Leer artículo →Desarrollo de softwareExplicación de la limitación de velocidad de API: algoritmos, encabezados y manejo de errores 429
La limitación de la tasa de API se explica con una simulación que ejecutamos: depósito de tokens, ventana fija, ventana deslizante, 429 respuestas, …
Leer artículo →Automatización de pruebasBurlarse en Python: unittest.mock, patch y los errores que hacen que las pruebas mientan
Burlarse en Python con unittest.mock, probado: Mock y return_value, side_effect, parches donde se usa un nombre, especificación y autospec, fechas d…
Leer artículo →Pruebas de softwareExplicación de la cobertura del código: cobertura de línea versus sucursal y lo que realmente significa 100%
Cobertura del código explicada con una ejecución real de cobertura.py: cobertura de línea, rama y condición, lectura de un informe, por qué una cobe…
Leer artículo →Bases de datos y SQLDELETE vs TRUNCATE vs DROP en SQL: diferencias, reversión y cuándo usar cada uno
DELETE vs TRUNCATE vs DROP explicado con SQL probado: qué elimina cada uno, reversión, activadores, restablecimiento de identidad, velocidad y en qu…
Leer artículo →Bases de datos y SQLVistas SQL explicadas: cree, use y evite los errores, con ejemplos
Vistas SQL explicadas con consultas que ejecutamos: creación de una vista, resultados en vivo, ocultación de columnas, rendimiento, vistas actualiza…
Leer artículo →Desarrollo de softwareInterfaz TypeScript versus tipo: diferencias reales, probadas con el compilador
Interfaz TypeScript versus tipo, verificado con el compilador real: qué pueden hacer ambos, qué puede hacer solo uno, fusión de declaraciones, exten…
Leer artículo →Desarrollo de softwarePython *args y **kwargs explicados: funciones flexibles con ejemplos claros
Python *args y **kwargs explicados con el código que ejecutamos: empaquetado y desempaquetado, orden de parámetros, argumentos solo de palabras clav…
Leer artículo →Desarrollo de softwareFunciones Lambda de Python: sintaxis, usos reales y cuándo no utilizarlas
Funciones lambda de Python explicadas con el código que ejecutamos: sintaxis, clasificación con clave, mapa y filtro, cierres, trampa de enlace tard…
Leer artículo →Inteligencia artificial¿Qué son los agentes de IA? Cómo funcionan, con un bucle de agente simple que puedes ejecutar
¿Qué son los agentes de IA? Una guía sencilla sobre el bucle del agente, las herramientas, la memoria y las barreras de seguridad, con un pequeño bu…
Leer artículo →DevOpsMonitoreo versus observabilidad: la verdadera diferencia, con registros, métricas y seguimientos
Explicación del monitoreo versus observabilidad: fallas conocidas y desconocidas, registros, métricas y seguimientos, un recorrido por incidentes de…
Leer artículo →DevOpsDocker Volumes versus Bind Mounts: persistir los datos del contenedor de la manera correcta
Se explican los volúmenes de Docker frente a los montajes de enlace: por qué desaparecen los datos del contenedor, volúmenes con nombre, montajes de…
Leer artículo →Automatización de pruebasTDD vs BDD: diferencias clave, una función creada en ambos sentidos y cuándo usar cada una
TDD vs BDD explicado con una característica de descuento construida en ambos sentidos: refactor rojo-verde con el código que ejecutamos, escenarios …
Leer artículo →Desarrollo de softwareGit merge vs rebase: diferencias, ejemplos y cuándo usar cada uno
Git merge vs rebase explicado con salida real del log, una tabla comparativa, la regla de oro del rebase y un flujo de trabajo seguro para equipos.
Leer artículo →Desarrollo de softwareList comprehension en Python: sintaxis, ejemplos y cuándo evitarla
List comprehension en Python explicada: sintaxis, filtros, if-else, bucles anidados, tiempos medidos y cuándo es mejor un bucle for normal.
Leer artículo →