Uso excesivo de expresiones lambda en Python

¿Qué son las expresiones lambda?  
Una expresión lambda es una sintaxis especial para crear funciones sin nombres. Estas funciones se denominan funciones lambda . Estas funciones lambda pueden tener cualquier cantidad de argumentos, pero solo una expresión junto con una declaración de devolución implícita. Las expresiones lambda devuelven objetos de función. Por ejemplo, considere la expresión lambda:  

lambda (arguments) : (expression)

Esta expresión lambda define una función sin nombre , que acepta dos argumentos y devuelve la suma de los dos argumentos. Pero, ¿cómo llamamos a una función sin nombre? La función lambda sin nombre definida anteriormente se puede llamar como:  

(lambda x, y: x + y)(1, 2)

Código 1: 

Python3

# Python program showing a use
# lambda function
 
# performing a addition of three number
x1 = (lambda x, y, z: (x + y) * z)(1, 2, 3)
print(x1)
 
# function using a lambda function     
x2 = (lambda x, y, z: (x + y) if (z == 0) else (x * y))(1, 2, 3)
print(x2)      

Producción: 

9
2

Aunque no se recomienda, el objeto de función devuelto por una expresión lambda se puede asignar a una variable. Vea el siguiente ejemplo en el que a una suma variable se le asigna un objeto de función devuelto por una expresión lambda. 
 

Python3

# Python program showing
# variable is storing lambda
# expression
 
# assigned to a variable
sum = lambda x, y: x + y
print(type(sum))
 
x1 = sum(4, 7)
print(x1)

Producción:  

11

Usos comunes de las expresiones lambda: 

  • Dado que las funciones lambda son anónimas y no requieren que se les asigne un nombre, generalmente se usan para llamar a funciones (o clases) que requieren un objeto de función como argumento . Definir funciones separadas para dichos argumentos de función no sirve de nada porque la definición de la función suele ser corta y solo se requieren una o dos veces en el código. Por ejemplo, el argumento clave de la función incorporada sorted()
     

Python3

# Python program showing
# using of normal function
def Key(x):
    return x%2
nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
sort = sorted(nums, key = Key)
print(sort)
  • Producción:
[0, 2, 4, 6, 8, 1, 3, 5, 7, 9]

Python3

# Python program showing use
# of lambda function
 
nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
sort_lambda = sorted(nums, key = lambda x: x%2)
print(sort_lambda)
  • Producción:
[0, 2, 4, 6, 8, 1, 3, 5, 7, 9]
  • Las funciones lambda son funciones en línea y, por lo tanto, se utilizan cuando existe la necesidad de llamadas a funciones repetitivas para reducir el tiempo de ejecución. Algunos de los ejemplos de tales escenarios son las funciones: map() , filter() y sorted(). Por ejemplo, 
     

Python3

# Python program showing a use
# of lambda function
 
nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
 
# using map() function
squares = map(lambda x: x * x, nums)
print(list(squares))
 
# using filter() function
evens = filter(lambda x: True if (x % 2 == 0)
                              else False, nums)
print(list(evens))

  
Pros y contras de las funciones lambda:  
Pros de las funciones lambda: 
 

  • Al ser anónimas, las funciones lambda se pueden pasar fácilmente sin asignarlas a una variable.
  • Las funciones Lambda son funciones en línea y, por lo tanto, se ejecutan comparativamente más rápido.
  • Muchas veces, las funciones lambda hacen que el código sea mucho más legible al evitar los saltos lógicos causados ​​por las llamadas a funciones. Por ejemplo, lea los siguientes bloques de código. 
     

Python3

# Python program performing
# operation using def()
def fun(x, y, z):
    return x*y+z
a = 1
b = 2
c = 3
 
# logical jump
d = fun(a, b, c)
print(d)    
  • Producción:
5

Python3

# Python program performing
# operation using lambda
 
d = (lambda x, y, z: x*y+z)(1, 2, 3)
print(d)
  • Producción:
5

Contras de las funciones lambda: 

  • Las funciones lambda solo pueden tener una expresión.
  • Las funciones Lambda no pueden tener una string de documentos.
  • Muchas veces, las funciones lambda dificultan la lectura del código. Por ejemplo, vea los bloques de código que se dan a continuación. 
     

Python3

def func(x):
    if x == 1:
        return "one"
    else if x == 2:
        return "two"
    else if x == 3:
        return "three"
    else:
        return "ten"
num = func(3)
print(num)
  • Producción:
three

Python3

# Python program showing use
# of lambda function
num = (lambda x: "one" if x == 1 else( "two" if x == 2
                       else ("three" if x == 3 else "ten")))(3)
print(num)
  • Producción:
three

  
Mal uso de las expresiones lambda: 

  • Asignación de expresiones lambda: la guía de estilo oficial de Python, PEP8 , desaconseja encarecidamente la asignación de expresiones lambda, como se muestra en el ejemplo a continuación.
func = lambda x, y, z: x*y + z
  • En su lugar, se recomienda escribir una función de una sola línea como,
def func(x, y, z): return x*y + z 
  • Si bien el segundo método fomenta el hecho de que las funciones lambda son anónimas, también es útil para rastrear durante la depuración. Ejecute el código a continuación para ver cómo def hace que los rastreos sean muy útiles. 
     

Python3

func = lambda x, y, z: x * y + z
print(func)
def func(x, y, z): return x * y + z
print(func)
  • Envolviendo expresiones lambda alrededor de funciones: muchas veces, las expresiones lambda se envuelven innecesariamente alrededor de funciones como se muestra a continuación.
nums = [-2, -1, 0, 1, 2]
sort = sorted(nums, key=lambda x: abs(x))
  • Si bien la sintaxis anterior es absolutamente correcta, los programadores deben comprender que todas las funciones en python se pueden pasar como objetos de función. Por lo tanto, el mismo código puede (y debe) escribirse como,
sort = sorted(nums, key=abs)
  • Pasar funciones innecesariamente: muchas veces, los programadores pasan funciones que realizan una sola operación. Consulte el siguiente código.
nums = [1, 2, 3, 4, 5]
summation = reduce(lambda x, y: x + y, nums)
  • La función lambda pasada anteriormente realiza una sola operación, agregando los dos argumentos. Se puede obtener el mismo resultado usando la función integrada sum , como se muestra a continuación. 
     
nums = [1, 2, 3, 4, 5]
summation = sum(nums)
  • Los programadores deben evitar el uso de expresiones lambda para operaciones comunes, ya que es muy probable que tengan una función integrada que proporcione los mismos resultados.

  
Uso excesivo de expresiones lambda: 

  • Uso de lambda para funciones no triviales: a veces, las funciones simples pueden no ser triviales. Vea el código a continuación.

Python3

details = [{'p':100, 'r':0.01, 'n':2, 't':4},
           {'p':150, 'r':0.04, 'n':1, 't':5},
           {'p':120, 'r':0.05, 'n':5, 't':2}]
sorted_details = sorted(details,
                        key=lambda x: x['p']*((1 + x['r']/
                                x['n'])**(x['n']*x['t'])))
print(sorted_details)
  • Producción:

[{‘n’: 2, ‘r’: 0,01, ‘t’: 4, ‘p’: 100}, {‘n’: 5, ‘r’: 0,05, ‘t’: 2, ‘p’: 120}, {‘n’: 1, ‘r’: 0,04, ‘t’: 5, ‘p’: 150}] 
 

  • Aquí, estamos clasificando los diccionarios sobre la base del interés compuesto . Ahora, vea el código escrito a continuación, que usa def .

Python3

details = [{'p':100, 'r':0.01, 'n':2, 't':4},
           {'p':150, 'r':0.04, 'n':1, 't':5},
           {'p':120, 'r':0.05, 'n':5, 't':2}]
def CI(det):
    '''sort key: compound interest, P(1 + r/n)^(nt)'''
    return det['p']*((1 + det['r']/det['n'])**(det['n']*det['t']))
sorted_details = sorted(details, key=CI)
print(sorted_details)
  • Producción:

[{‘n’: 2, ‘r’: 0,01, ‘t’: 4, ‘p’: 100}, {‘n’: 5, ‘r’: 0,05, ‘t’: 2, ‘p’: 120}, {‘n’: 1, ‘r’: 0,04, ‘t’: 5, ‘p’: 150}] 
 

  • Aunque ambos códigos hacen lo mismo, el segundo que usa def es mucho más legible. La expresión escrita aquí debajo de la lambda puede ser simple, pero tiene un significado (fórmula para el interés compuesto). Por lo tanto, la expresión no es trivial y merece un nombre. El uso de expresiones lambda para funciones no triviales reduce la legibilidad del código.
  • Usar lambdas cuando hay varias líneas ayudaría: si usar una función de varias líneas hace que el código sea más legible, no vale la pena usar expresiones lambda para reducir algunas líneas de código. Por ejemplo, vea el código a continuación.

personas = [(‘sam’, ‘M’, 18), (‘susan’, ‘F’, 22), (‘joy’, ‘M’, 21), (‘lucy’, ‘F’, 12) ] 
sorted_people = sorted(personas, clave=lambda x: x[1]) 
 

  • También vea el siguiente código que usa def .
def Key(person):
    name, sex, age = person
    return sex
sorted_people = sorted(people, key=Key)
  • Vea cómo el desempaquetado de tuplas en el segundo bloque de código lo hace mucho más legible y lógico. La legibilidad del código debe ser la máxima prioridad de un programador, que trabaja en un entorno colaborativo.
  • Uso de expresiones lambda para map y filter: las lambdas se usan muy comúnmente con map() y filter() como se muestra.

Python3

nums = [0, 1, 2, 3, 4, 5]
mapped = map(lambda x: x * x, nums)
filtered = filter(lambda x: x % 2, nums)
print(list(mapped))
print(list(filtered))

Python3

nums = [0, 1, 2, 3, 4, 5]
mapped = (x * x for x in nums)
filtered = (x for x in nums if x % 2 == 1)
print(list(mapped))
print(list(filtered))
  • A diferencia de map() y filter(), las expresiones generadoras son funciones de propósito general del lenguaje python. Así, los generadores mejoran la legibilidad del código. Mientras que map() y filter() requieren un conocimiento previo de estas funciones.
     
  • Uso de funciones de orden superior: Las funciones que aceptan otros objetos de función como argumentos se denominan funciones de orden superior (es decir, map() y filter()), que son comunes en la programación funcional . Como se indicó anteriormente, las expresiones lambda se usan comúnmente como argumentos de función de funciones de orden superior. Compare los dos bloques de código que se muestran a continuación. 
    Usando la función de orden alto reduce()
nums = [1, 2, 3, 4, 5]
product = reduce(lambda x, y: x*y, nums, 1)
  • Sin utilizar la función de orden superior
nums = [1, 2, 3, 4, 5]
def multiply(nums):
    prod = 1
    for number in nums:
        prod *= number
    return prod
product = multiply(nums)
  • Mientras que el primer bloque usa menos líneas de código y no es tan difícil de entender, los programadores sin experiencia en programación funcional encontrarán que el segundo bloque de código es mucho más legible. A menos que se practique el paradigma de programación funcional adecuado, no se aprecia pasar una función a otra función, ya que puede reducir la legibilidad.

Publicación traducida automáticamente

Artículo escrito por Manthanchauhan y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *