¿Por qué es útil la lata de pitón?

Estoy tratando de averiguar lambda de Python. ¿La lambda es uno de esos temas de lenguaje "interesantes" que debes olvidar en la vida real?

Estoy seguro de que hay algunos casos extremos en los que esto puede ser necesario, pero dada su ambigüedad, el potencial para redefinirlo en futuras versiones (mi suposición basada en sus diversas definiciones) y la claridad de codificación reducida, ¿debería evitarse?

Esto me recuerda a un desbordamiento (desbordamiento de búfer) de tipos C: una indicación de la variable superior y una sobrecarga para configurar otros valores de campo. Se siente como una clase magistral, pero una pesadilla de codificador de apoyo.

826
20 мая '09 в 23:40 2009-05-20 23:40 configurado para el 20 de mayo de 2009 a las 11:40 2009-05-20 23:40
@ 26 respuestas

¿Estás hablando de funciones lambda ? Como

 lambda x: x**2 + 2*x - 5 

Esas cosas son bastante útiles. Python admite un estilo de programación llamado programación funcional, donde puede pasar funciones a otras funciones. Ejemplo:

 mult3 = filter(lambda x: x % 3 == 0, [1, 2, 3, 4, 5, 6, 7, 8, 9]) 

establece mult3 en [3, 6, 9] , aquellos elementos de la lista original que son múltiplos de 3. Es más corto (y, uno puede argumentar, más claro) que

 def filterfunc(x): return x % 3 == 0 mult3 = filter(filterfunc, [1, 2, 3, 4, 5, 6, 7, 8, 9]) 

Por supuesto, en este caso particular, podría hacer lo mismo que entender la lista:

 mult3 = [x for x in [1, 2, 3, 4, 5, 6, 7, 8, 9] if x % 3 == 0] 

(o incluso como range(3,10,3) ), pero hay muchos otros casos de uso más complejos en los que no se puede usar la información de la lista, y la función lambda puede ser la forma más corta de escribir algo.

  • Devuelve una función de otra función

     >>> def transform(n): ... return lambda x: x + n ... >>> f = transform(3) >>> f(4) 7 

    Esto se usa a menudo para crear shells funcionales, como los decoradores de Python.

  • Combinando elementos de una secuencia iterativa con reduce()

     >>> reduce(lambda a, b: '{}, {}'.format(a, b), [1, 2, 3, 4, 5, 6, 7, 8, 9]) '1, 2, 3, 4, 5, 6, 7, 8, 9' 
  • Ordenar por clave alternativa

     >>> sorted([1, 2, 3, 4, 5, 6, 7, 8, 9], key=lambda x: abs(5-x)) [5, 4, 6, 3, 7, 2, 8, 1, 9] 

Regularmente uso funciones lambda. Me tomó un tiempo acostumbrarme a ellos, pero al final me di cuenta de que eran una parte muy valiosa del idioma.

902
20 мая '09 в 23:52 2009-05-20 23:52 La respuesta es dada por David Z el 20 de mayo de 2009 a las 23:52 2009-05-20 23:52

lambda es solo una forma elegante de decir function . Además de su nombre, no hay nada oculto, aterrador o misterioso. Cuando lea la siguiente línea, reemplace lambda con la function en su mente:

 >>> f = lambda x: x + 1 >>> f(3) 4 

Simplemente define la función x . Algunos otros idiomas, como R , dicen esto explícitamente:

border=0
 > f = function(x) { x + 1 } > f(3) 4 

Tu ves Esta es una de las cosas más naturales en la programación.

329
16 янв. La respuesta la da el usuario 251650 16 de enero. 2010-01-16 18:03 '10 a las 18:03 2010-01-16 18:03

Resumen de dos líneas:

  • Cierre : Muy útil. Estudíalos, utilízalos, amor.
  • lambda clave de Python lambda : innecesaria, a veces útil. Si se encuentra haciendo algo de manera remota con él, déjelo a un lado y determine la función real.
94
21 мая '09 в 1:37 2009-05-21 01:37 respondió a John Fouhy el 21 de mayo de 2009 a la 1:37 2009-05-21 01:37

Lambda es parte de un mecanismo de abstracción muy importante que se ocupa de funciones de un orden superior. Para obtener una comprensión adecuada de su valor, consulte las lecciones de alta calidad de Abelson y Sussman y lea el libro SICP.

Estos son problemas reales en el negocio de software moderno y se están haciendo cada vez más populares.

71
20 мая '09 в 23:49 2009-05-20 23:49 la respuesta la da egaga el 20 de mayo de 2009 a las 23:49 2009-05-20 23:49

Dudo que la lambda desaparezca. Ver el post de Guido que finalmente abandona el intento de eliminarlo. Ver también conflicto de contorno .

Puede consultar esta publicación para obtener información más detallada sobre la transacción detrás de la funcionalidad de Python: http://python-history.blogspot.com/2009/04/origins-of-pythons-functional-features.html

Es curioso que las funciones de visualización, filtrado y reducción, que inicialmente motivaron la introducción de lambda y otras funciones funcionales, fueron reemplazadas en gran medida por expresiones de listas y expresiones del generador. De hecho, la función de acceso directo se ha eliminado de la lista de funciones integradas en Python 3.0. (Sin embargo, no es necesario enviar quejas sobre la eliminación de un lambda, un mapa o un filtro: permanecen.: -)

Mis propios dos centavos: Rara vez lambda vale la pena, qué claro. Como regla general, hay una solución más clara que no incluye lambda.

57
20 мая '09 в 23:46 2009-05-20 23:46 la respuesta se da rhettg 20 de mayo de 2009 a las 23:46 2009-05-20 23:46

Las lambdas son extremadamente útiles en la programación de GUI. Por ejemplo, supongamos que crea un grupo de botones y desea utilizar una devolución de llamada parametrizada, en lugar de una devolución de llamada única para cada botón. Lambda te permite manejar fácilmente esto:

 for value in ["one","two","three"]: b = tk.Button(label=value, command=lambda arg=value: my_callback(arg)) b.pack() 

(Nota: aunque esta pregunta formula específicamente una pregunta sobre lambda , también puede usar functools.partial para obtener el mismo tipo de resultado)

La alternativa es crear una devolución de llamada por separado para cada botón, lo que puede llevar a la duplicación de código.

56
24 апр. Respuesta dada por Bryan Oakley el 24 de abril. 2011-04-24 19:48 '11 a las 19:48 2011-04-24 19:48

En Python, lambda es solo una forma de definir funciones en línea,

  a = lambda x: x + 1 распечатать a (1) Код> 

y ..

  def a (x): return x + 1 распечатать a (1) Код> 

.. son precisos .

No hay nada que puedas hacer con un lambda que no puedas hacer con una función normal; hay un objeto en las funciones de Python, como todo lo demás, y lambdas simplemente define una función:

<Preliminar> <código → → a = lambda x: x + 1 →> ingresar) <tipo 'función'> Código>

Sinceramente, creo que la palabra clave lambda es redundante en Python: nunca tuve que usarlos (o podría ver cuando se usa una función regular, entender la lista o una de las muchas funciones integradas podría ser mejor utilizada)

Para un ejemplo completamente aleatorio del artículo "¡Python lambda está roto!" :

Para averiguar cómo se rompe lambda, intente crear una lista de funciones fs = [f0,..., f9] , donde fi (n) = я + n , primer intento:

<Preliminar> <código → → fs = [(lambda n: i + n) para i en el rango (10)] →> fs [3] (4) 13 Código>

Yo diría que incluso si funcionara, sería horrible e "irrelevante", la misma funcionalidad podría escribirse de muchas otras formas, por ejemplo:

<Preliminar> <código → → n = 4 →> [i + n para i en el rango (10)] [4, 5, 6, 7, 8, 9, 10, 11, 12, 13] Código>

Sí, esto no es lo mismo, pero nunca he tenido una razón para crear un grupo de funciones lambda en la lista. Esto puede tener sentido en otros idiomas, pero Python no es Haskell (o Lisp, o ...)

Tenga en cuenta que podemos usar lambda y aún así derivar de la siguiente manera:

<Preliminar> <código → → fs = [(lambda n, i = i: i + n) para i en el rango (10)] →> fs [3] (4) 7 Código>

Editar:

Hay varios casos en que lambda es útil, por ejemplo, a menudo es conveniente cuando se conectan señales en aplicaciones PyQt, por ejemplo:

  w = PyQt4.QtGui.QLineEdit() w.textChanged.connect(событие lambda: dothing()) Код> 

Simplemente ejecutando w.textChanged.connect(dothing) llamará al método dothing con un argumento de event adicional y causará un error. Usando herramientas lambda, podemos eliminar suavemente el argumento sin definir la función de envoltura.

31
21 мая '09 в 5:03 2009-05-21 05:03 respondió a dbr el 21 de mayo de 2009 a las 5:03 2009-05-21 05:03

Encuentro que lambda es útil para una lista de funciones que hacen lo mismo, pero para diferentes circunstancias. Como las reglas plurales de Mozilla .

 plural_rules = [ lambda n: 'all', lambda n: 'singular' if n == 1 else 'plural', lambda n: 'singular' if 0 <= n <= 1 else 'plural', ... ] # Call plural rule #1 with argument 4 to find out which sentence form to use. plural_rule[1](4) # returns 'plural' 

Si necesitas definir una función para todos aquellos que están locos hasta el final. También estaría bien con nombres de funciones como plural_rule_1 , plural_rule_2 , etc. Y necesitará eval() cuando sea una plural_rule_2 del identificador de variable de función.

28
16 янв. La respuesta se da Tor Valamo 16 jan. 2010-01-16 18:43 '10 a las 18:43 2010-01-16 18:43

Con casi todo lo que puede hacer con lambda , puede hacerlo mejor con funciones nombradas o expresiones de lista y generador.

En consecuencia, en su mayor parte, solo tiene que ser uno de ellos en cualquier situación (con la posible excepción del código cero escrito en un intérprete interactivo).

26
20 мая '09 в 23:45 2009-05-20 23:45 Aaron Maenpaa da la respuesta el 20 de mayo de 2009 a las 23:45 2009-05-20 23:45

He estado usando Python durante varios años y nunca he encontrado una situación en la que necesito lambda. De hecho, como dice el tutorial , es solo para el azúcar sintáctica.

19
20 мая '09 в 23:47 2009-05-20 23:47 Matt Schmidt da la respuesta el 20 de mayo de 2009 a las 23:47 2009-05-20 23:47

No puedo hablar con python sobre la implementación específica de lambda, pero en general, las funciones de lambda son realmente convenientes. Este es el método principal (quizás incluso el método) de la programación funcional, y también son muy útiles en programas orientados a objetos. Para ciertos tipos de problemas, son la mejor solución, por lo que, por supuesto, ¡no debe olvidarse!

Le sugiero que lea la función de cerrar y mapear (que se refiere a documentos de Python, pero existe en casi todos los idiomas que admiten construcciones funcionales) para ver por qué es útil.

16
20 мая '09 в 23:45 2009-05-20 23:45 la respuesta se da rmeador 20 de mayo de 2009 a las 23:45 2009-05-20 23:45

La función lambda es una forma no burocrática de crear una función.

Que es Por ejemplo, supongamos que tiene su función principal y que necesita valores cuadrados. Echemos un vistazo a la forma tradicional y la forma de lambda:

La forma tradicional:

 def main(): ... ... y = square(some_number) ... return something def square(x): return x**2 

Lambda:

 def main(): ... square = lambda x: x**2 y = square(some_number) return something 

¿Ves la diferencia?

Las funciones Lambda se combinan muy bien con listas, como listas o mapas. De hecho, entender la lista es una forma “pitónica” de expresarte usando lambda. Ejemplo:

 >>>a = [1,2,3,4] >>>[x**2 for x in a] [1,4,9,16] 

Veamos qué significa cada elemento de sintaxis:

[]: "Dame una lista"

x ** 2: "usando esta característica recién nacida"

para x en a: "en cada elemento de a <

¿Es conveniente? La creación de tales funciones. Vamos a reescribirlo usando lambda:

 >>> square = lambda x: x**2 >>> [square(s) for x in a] [1,4,9,16] 

Ahora vamos a usar un mapa que es el mismo, pero más neutral para el idioma. Las tarjetas aceptan 2 argumentos:

(i) una función

(ii) iterable

Y le da una lista en la que cada elemento que se aplica a cada elemento es iterable.

Entonces, usando el mapa, tendríamos:

 >>> a = [1,2,3,4] >>> squared_list = map(lambda x: x**2, a) 

Si dominas las lambdas y el mapeo, tendrás mucho poder para manipular los datos de una manera concisa. Las funciones Lambda no están ocultas ni aclaran la claridad del código. No confundas algo nuevo con algo nuevo. Cuando empieces a usarlos, lo encontrarás muy comprensible.

16
11 окт. Respuesta dada por Lucas Ribeiro el 11 de octubre. 2013-10-11 06:03 '13 a las 6:03 am 2013-10-11 06:03

Una de las cosas agradables de la lambda , que, en mi opinión, es sobria, es que es una forma de posponer la evaluación de formas simples hasta que se necesita el valor. Déjame explicarte.

Muchos procedimientos de la biblioteca se implementan de tal manera que permiten que algunos parámetros sean desafiantes (de los cuales lambda es uno). La idea es que el valor real solo se calculará en el momento en que se use (más bien, cuando se llame). Un ejemplo (creado) puede ayudar a ilustrar este punto. Supongamos que tiene una subrutina que debía registrar una marca de tiempo determinada. Desea que la subrutina utilice la hora actual menos 30 minutos. Usted lo llamaría así.

 log_timestamp(datetime.datetime.now() - datetime.timedelta(minutes = 30)) 

Ahora suponga que la función real se llamará solo cuando ocurra un evento determinado, y desea que la marca de tiempo se calcule solo en ese momento. Puedes hacerlo así:

 log_timestamp(lambda : datetime.datetime.now() - datetime.timedelta(minutes = 30)) 

Suponiendo que log_timestamp puede manejar llamadas como esta, lo evaluará cuando sea necesario y obtendrá una marca de tiempo en ese momento.

Por supuesto, hay formas alternativas de hacerlo (por ejemplo, usando el módulo del operator ), pero espero que haya transmitido esta pregunta.

Actualización: Aquí hay un ejemplo un poco más específico del mundo real.

Actualización 2: Creo que este es un ejemplo de lo que se llama thunk .

13
16 янв. La respuesta es dada por Noufal Ibrahim el 16 de enero. 2010-01-16 18:30 '10 a las 18:30 2010-01-16 18:30

Como se indicó anteriormente, el operador lambda en Python define una función anónima, y ​​en las funciones de Python, un cierre. Es importante no confundir el concepto de cierres con el operador lambda, que para ellos es simplemente metadona sintáctica.

Cuando comencé a trabajar en Python hace unos años, usé mucho lambda, pensando que eran geniales y listas. Sin embargo, escribí y debería mantener un sitio grande escrito en Python, del orden de varios miles de puntos funcionales. Aprendí por experiencia que las lambdas podrían estar bien para hacer prototipos, pero no ofrecen nada sobre las funciones integradas (llamadas cierres), excepto para almacenar algunos drenajes de teclas, y algunas veces no.

Básicamente se trata de varios puntos:

  • Software más fácil de leer que está escrito explícitamente usando nombres significativos. Los cierres anónimos, por definición, no pueden tener un nombre significativo, ya que no tienen nombre. Aparentemente, esta brevedad también infecta los parámetros lambda por alguna razón, por lo que a menudo vemos ejemplos como lambda x: x + 1
  • es más fácil reutilizar los bloqueos con nombre, ya que pueden llamarse por nombre más de una vez cuando hay un nombre para hacer referencia a ellos.
  • es más fácil depurar el código que utiliza cierres con nombre en lugar de lambdas, porque el nombre se mostrará en las trazas y alrededor del error.

Esta es razón suficiente para redondearlos y convertirlos en nombres privados. Sin embargo, tengo otros dos descontentos con cierres anónimos.

La primera insatisfacción es solo otra palabra clave innecesaria que obstruye el lenguaje.

El segundo descontento es más profundo y a nivel de paradigma, es decir, No me gusta que promuevan un estilo de programación funcional, porque este estilo es menos flexible que el proceso de paso de mensajes, el estilo orientado a objetos o el procedimiento, porque el cálculo lambda no es Turing completo (afortunadamente en Python, todavía podemos salir de él). de esta restricción incluso dentro de la lambda). Las razones por las que siento que las lambdas están promoviendo este estilo:

  • Hay un retorno implícito, es decir, Parece que deberían ser funciones.

  • Proporcionan un mecanismo alternativo para ocultar estados para otro mecanismo más explícito, más legible, más reutilizable y más general: los métodos.

Intento escribir python sin lambda y eliminar lambda a simple vista. Creo que Python será un poco mejor lenguaje sin lambda, pero esta es solo mi opinión.

11
18 окт. Respuesta dada por Mike A el 18 de octubre. 2010-10-18 21:01 '10 a las 21:01 2010-10-18 21:01

Las Lambdas son construcciones realmente muy poderosas que se derivan de ideas en la programación funcional, y esto es algo que de ninguna manera será fácilmente revisado, redefinido o eliminado en el futuro cercano de Python. Le ayudan a escribir código que es más poderoso porque le permite pasar funciones como parámetros, por lo tanto, la idea de funciones como ciudadanos de primera clase.

Lambdas generalmente está confundido, pero una vez que tenga una comprensión sólida, puede escribir un código limpio y elegante como este:

 squared = map(lambda x: x*x, [1, 2, 3, 4, 5]) 

La línea de código anterior devuelve la lista de cuadrados de los números en la lista. Por supuesto, también puedes hacerlo como:

 def square(x): return x*x squared = map(square, [1, 2, 3, 4, 5]) 

Obviamente, el código antiguo es más corto, y esto es especialmente cierto si pretende utilizar la función de mapa (o cualquier función similar que tome una función como parámetro) en un solo lugar. También hace que el código sea más intuitivo y elegante.

Además, como señaló @David Zaslavsky en su respuesta, la comprensión de las listas no siempre tiene un camino, especialmente si su lista debería obtener valores de algún camino matemático oscuro.

Desde un punto de vista más práctico, una de las mayores ventajas de lambdas para mí recientemente fue la interfaz gráfica y la programación basada en eventos. Si observas las devoluciones de llamada en Tkinter, todo lo que toman como argumentos es el evento que las activó. Por ejemplo

 def define_bindings(widget): widget.bind("<Button-1>", do-something-cool) def do-something-cool(event): #Your code to execute on the event trigger 

Ahora, si tienes algún argumento? Algo tan simple como pasar 2 argumentos para almacenar las coordenadas del clic del mouse. Puede hacerlo de la siguiente manera:

 def main(): # define widgets and other imp stuff x, y = None, None widget.bind("<Button-1>", lambda event: do-something-cool(x, y)) def do-something-cool(event, x, y): x = event.x y = event.y #Do other cool stuff 

Ahora puede argumentar que esto se puede hacer usando variables globales, pero ¿realmente quiere que su cabeza se preocupe por la gestión de la memoria y las fugas, especialmente si la variable global se usará solo en un lugar en particular? Simplemente será un mal estilo de programación.

En resumen, las lambdas son increíbles y nunca deben ser subestimadas. Python lambdas no es lo mismo que LISP lambdas (más potente), pero realmente puedes hacer muchas cosas mágicas con ellos.

11
24 мая '13 в 16:02 2013-05-24 16:02 la respuesta se da varagrawal 24 de mayo de 13 a 16:02 2013-05-24 16:02

Lambdas está profundamente conectado con el estilo de programación funcional en su conjunto. La idea de que puede resolver problemas aplicando una función a algunos datos y combinando los resultados es lo que Google utiliza para implementar la mayoría de sus algoritmos.

Los programas escritos en el estilo de programación funcional son fácilmente paralelizados y, por lo tanto, se vuelven cada vez más importantes con las modernas máquinas de múltiples núcleos. En definitiva, NO, no hay que olvidarlos.

8
20 мая '09 в 23:46 2009-05-20 23:46 Yogi 20 de mayo de 2009 a las 23:46 2009-05-20 23:46

Las primeras felicitaciones que lograron averiguar lambda. En mi opinión, este es un diseño realmente poderoso para el trabajo. La tendencia en estos días a los lenguajes de programación funcionales es ciertamente una indicación de que no debe evitarse y no se redefinirá en un futuro próximo.

Solo necesitas pensar un poco diferente. Estoy seguro de que te gustará pronto. Pero ten cuidado si solo tratas con python. Dado que lambda no es un cierre real, de alguna manera está "roto": los pitones lambda no funcionan

6
20 мая '09 в 23:47 2009-05-20 23:47 La respuesta fue dada por Norbert Hartl el 20 de mayo de 2009 a las 23:47 2009-05-20 23:47

Puedo darte un ejemplo de donde realmente necesito lambda. Hago un programa gráfico, donde el clic derecho en el archivo y le asigna una de las tres opciones. Оказывается, что в Tkinter (программа сопряжения GUI, в которой я пишу это), когда кто-то нажимает кнопку, она не может быть назначена команде, которая принимает аргументы. Поэтому, если бы я выбрал один из вариантов и хотел, чтобы результат моего выбора был таким:

 print 'hi there'