Calificación:
  • 0 voto(s) - 0 Media
  • 1
  • 2
  • 3
  • 4
  • 5
Diferencia entre lambda y método en un map()
#1
Hola. Disculpad mi torpeza, pero soy MUY novato. Estoy intentando asimilar las funciones de orden superior, en concreto lambda, filter y map. En principio me pareció bastante sencillo. Pero en el siguiente ejemplo, me confunde el diferente comportamiento de un método y lo que yo creía que era su "versión lambda" (seguramente también estoy equivocado en esto):  

class Profesion:
    def __init__(self, empleo, codigo):
        self.empleo = empleo
        self.codigo = codigo


    def __str__(self):
        return "{}, código {}".format(self.empleo, self.codigo)


empleados = [
    Profesion("Analista", 4),
    Profesion("Diseñador", 6),
    Profesion("Consultor", 3),
    Profesion("Programador", 5)

]
   

#El siguiente map() suma 20 al argumento "código"   
actualizar = map(lambda a: a.codigo + 20, empleados)
for a in actualizar:
print (a, end=" ")

24 26 23 25

#pero no modifica la lista original
for empleado in empleados:
    print(empleado)   

Analista, código 4
Diseñador, código 6
Consultor, código 3
Programador, código 5


#Pero este map() suma 20 al argumento "código" ...   
def incrementar(a):
    a.codigo += 20
    return a.codigo

actualizar2 = map(incrementar, empleados)
for a in actualizar2:
  print(a, end=" ") 

24 26 23 25 

#...y sí modifica la lista original.
for empleado in empleados:
    print(empleado)  

Analista, código 24
Diseñador, código 26
Consultor, código 23
Programador, código 25


>>>Cualquier ayuda será bien recibida Smile
Responder
#2
Hola, ¿cómo estás?

El problema es que tu función incrementar() no es equivalente a tu función lambda. En tu lambda tenés:

  1. lambda a: a.codigo + 20


Que es equivalente a esto:

  1. def incrementar(a):
  2. return a.codigo + 20


Pero vos tenés otra función:

  1. def incrementar(a):
  2. a.codigo += 20
  3. return a.codigo


Ahí estás cambiando el valor de a.codigo (porque a.codigo += 20 es igual a a.codigo = a.codigo + 20). Luego podés ver los cambios en tu lista porque los argumentos en Python son por referencia, no por valor, por lo cual tu argumento "a" no es una copia de un empleado, sino el empleado mismo.

Te paso algunos artículos que pueden servirte:

Sobre las funciones lambda: https://recursospython.com/guias-y-manua...es-lambda/.

Sobre los parámetros por referencia: https://recursospython.com/guias-y-manua...eferencia/ y https://recursospython.com/guias-y-manua...lenguajes/.

Saludos!
Responder
#3
¡Fantástico! Muchas gracias por tu respuesta Francisco. Tanto tu explicación como tus artículos de referencia, me sirvieron de MUCHA ayuda.
¿Crees que quizá el problema radicaba en que, básicamente yo había querido convertir en lambda un método que no era susceptible de ello, ya que una función lambda solo admite una expresión, y el método que yo quería transformar tenía dos?:

1.
a.codigo += 20

2.
return a.codigo
Responder
#4
¡De nada! Sí, más bien el problema es que esto:

  1. a.codigo += 20


directamente no es una expresión (no tiene ningún resultado), por lo tanto no puede constituirse como una función lambda. Además, como bien decís, en una lambda solo puede haber una expresión.

Saludos!
Responder


Salto de foro:


Usuarios navegando en este tema: 2 invitado(s)