2012-01-23 16 views

Respuesta

105

key es una función que se llamará para transformar los elementos de la colección antes de que se comparen. El parámetro pasado a key debe ser algo que se pueda llamar.

El uso de lambda crea una función anónima (que es invocable). En el caso de sorted, el llamable solo toma un parámetro. Python's lambda es bastante simple. Solo puede hacer y devolver una cosa realmente.

La sintaxis de lambda es la palabra lambda seguida de la lista de nombres de parámetros y luego un solo bloque de código. La lista de parámetros y el bloque de código están delineados por dos puntos. Esto es similar a otras construcciones en python, como while, for, if y así sucesivamente. Son todas las declaraciones que generalmente tienen un bloque de código. Lambda es solo otra instancia de una declaración con un bloque de código.

Podemos comparar el uso de lambda con el de def para crear una función.

adder_lambda = lambda parameter1,parameter2: parameter1+parameter2 
def adder_regular(parameter1, parameter2): return parameter1+parameter2 

lambda nos da una forma de hacer esto sin asignar un nombre. Lo que lo hace ideal para usar como parámetro de una función.

variable se usa dos veces aquí porque en la parte izquierda del colon se encuentra el nombre de un parámetro y en el lado derecho se está utilizando en el bloque de código para calcular algo.

+7

nota (a OP): se debe evitar asignar un lambda a un nombre (es decir, usarlo de una manera que no sea una función anónima). si te encuentras haciendo esto, probablemente deberías usar un 'def'. – wim

24

lambda es una palabra clave de Python que se utiliza para generate anonymous functions.

>>> (lambda x: x+2)(3) 
5 
+2

¿Por qué hay paréntesis alrededor de cada uno? –

+16

Los pareados son alrededor de '3' porque se pasan a una función. Los parens están alrededor de la lambda para que la expresión no se analice como 'lambda x: x + 2 (3)', que no es válida ya que '2' no es una función. –

10

El variable izquierda de la : es un nombre de parámetro. El uso de variable a la derecha está haciendo uso del parámetro.

Medios casi exactamente lo mismo que:

def some_method(variable): 
    return variable[0] 
3

lambda es una función anónima, no es una función arbitraria. El parámetro que se acepta sería la variable con la que está trabajando y la columna en la que lo está ordenando.

41

Creo que todas las respuestas aquí cubrir el núcleo de lo que la función lambda hace en el contexto de la ordenada() bastante bien, sin embargo, todavía siento que falta una descripción que conduzca a una comprensión intuitiva, así que aquí está mi granito de arena.

Para completar, expondré lo obvio por adelantado: sorted() devuelve una lista de elementos ordenados y si queremos ordenar de una manera particular o si queremos ordenar una lista compleja de elementos (por ejemplo, listas anidadas o una lista de tuplas) podemos invocar el argumento clave.

Para mí, la comprensión intuitiva del argumento clave, por qué tiene que ser invocable, y el uso de lambda como la función invocable (anónima) para lograr esto viene en dos partes.

  1. Usar lamba en última instancia significa que no tiene que escribir (definir) una función completa, como la que proporciona un ejemplo de sblom. Las funciones de Lambda se crean, usan e inmediatamente se destruyen, por lo que no alteran tu código con más código que solo se usará una vez. Esto, como yo lo entiendo, es la utilidad central de la función lambda y sus aplicaciones para tales roles son amplias. Su sintaxis es puramente por convención, que es, en esencia, la naturaleza de la sintaxis programática en general. Aprenda la sintaxis y termine con ella.

sintaxis Lambda es el siguiente:

lambda input_variable (s): sabroso un trazador de líneas

por ejemplo

In [1]: f00 = lambda x: x/2 

In [2]: f00(10) 
Out[2]: 5.0 

In [3]: (lambda x: x/2)(10) 
Out[3]: 5.0 
  1. La idea detrás del argumento clave es que se necesita en un conjunto de instrucciones que esencialmente apuntan 'ordenados()' en la que la lista de elementos que debe utilizar para ordenar por. Cuando dice 'clave =', lo que realmente significa es: a medida que recorro la lista un elemento a la vez (es decir, para e en la lista), voy a pasar el elemento actual a la función que proporciono en la clave argumento y usar eso para crear una lista transformada que me informará sobre el orden de la lista ordenada final.

Compruébelo: ejemplo

mylist = [3,6,3,2,4,8,23] 
sorted(mylist, key=WhatToSortBy) 

Base:

sorted(mylist) 

[2, 3, 3, 4, 6, 8, 23] # todos los números están en orden de pequeño a grande.

Ejemplo 1:

mylist = [3,6,3,2,4,8,23] 
sorted(mylist, key=lambda x: x%2==0) 

[3, 3, 23, 6, 2, 4, 8] # ¿Tiene este resultado ordenada tiene sentido intuitivo para usted?

Observe que mi función lambda indicó ordenada para verificar si (e) era par o impar antes de la clasificación.

PERO ESPERE! Puede (o quizás debería) preguntarse dos cosas: primero, ¿por qué mis probabilidades vienen antes que mis pares (dado que mi valor clave parece estar diciendo a mi función ordenada que priorice los niveles usando el operador de mod en x% 2 == 0) y segundo, ¿por qué mis pares están fuera de orden? 2 viene antes de las 6 ¿verdad? Al analizar este resultado, aprenderemos algo más profundo sobre cómo funciona el argumento "clave" ordenado(), especialmente en conjunto con la función lambda anónima.

En primer lugar, se dará cuenta de que, si bien las probabilidades se presentan antes de los pares, los pares no están ordenados. ¿¿Por qué es esto??Lets read the docs:

Funciones de las teclas A partir de Python 2.4, tanto list.sort() y ordenados() añade un parámetro clave para especificar una función a ser llamada en cada elemento de la lista antes de hacer comparaciones.

Tenemos que leer un poco entre líneas aquí, pero lo que esto nos dice es que la función de clasificación solo se llama una vez, y si especificamos el argumento clave, entonces ordenamos por el valor que la función clave nos apunta a.

¿Qué significa el ejemplo que utiliza un módulo de retorno? Un valor booleano: True = 1, False = 0. Entonces, ¿cómo se soluciona el problema con esta clave? Básicamente, transforma la lista original en una secuencia de 1s y 0s.

[3,6,3,2,4,8,23] se convierte en [0,1,0,1,1,1,0]

Ahora estamos llegando a alguna parte. ¿Qué obtienes cuando clasificas la lista transformada?

[0,0,0,1,1,1,1]

bien, así que ahora sabemos por qué las probabilidades vienen antes de que los iguala. Pero la siguiente pregunta es: ¿por qué el 6 todavía viene antes de los 2 en mi lista final? Bueno, eso es fácil, ¡es porque la clasificación solo ocurre una vez! La última pregunta es: ¿cómo puedo pensar conceptualmente sobre cómo el orden de mis valores booleanos vuelve a transformarse en los valores originales cuando imprimo la lista ordenada final?

Sorted() es un método integrado que (hecho curioso) utiliza un algoritmo de clasificación híbrido llamado Timsort que combina aspectos de tipo de fusión e inserción. Me parece claro que cuando lo llamas, hay un mecánico que mantiene estos valores en la memoria y los agrupa con su identidad booleana (máscara) determinada por (...!) La función lambda. El orden está determinado por su identidad booleana calculada a partir de la función lambda, pero tenga en cuenta que estas sublistas (de uno y ceros) no están ordenadas por sus valores originales. Por lo tanto, la lista final, aunque organizada por Odds y Evens, no está ordenada por sublista (los pares en este caso están fuera de servicio). El hecho de que las probabilidades estén ordenadas es porque ya estaban en orden por coincidencia en la lista original. La conclusión de todo esto es que cuando lambda realiza esa transformación, se conserva el orden original de las sublistas.

Entonces, ¿cómo se relaciona todo esto con la pregunta original, y más importante aún, nuestra intuición sobre cómo debemos implementar sorted() con su argumento clave y lambda?

Esa función lambda se puede considerar como un puntero que apunta a los valores que necesitamos ordenar, ya sea un puntero mapeando un valor a su booleano transformado por la función lambda, o si es un elemento particular en un anidado list, tuple, dict, etc. de nuevo determinado por la función lambda.

Intentemos y pronosticamos qué sucede cuando ejecuto el siguiente código.

mylist = [(3, 5, 8), (6, 2, 8), (2, 9, 4), (6, 8, 5)] 
sorted(mylist, key=lambda x: x[1]) 

Mis métodos ordenados obviamente dicen, "Ordene esta lista". El argumento clave lo hace un poco más específico al decir, para cada elemento (x) en mylist, devolver el índice 1 de ese elemento, luego ordenar todos los elementos de la lista original 'mylist' por el orden ordenado de la lista calculada por la función lambda.Como tenemos una lista de tuplas, podemos devolver un elemento indexado de esa tupla. Así tenemos:

[(6, 2, 8), (3, 5, 8), (6, 8, 5), (2, 9, 4)]

Run ese código, y encontrarás que este es el orden. Intenta indexar una lista de enteros y verás que el código se rompe.

Esta fue una explicación larga, pero espero que esto ayude a 'ordenar' su intuición sobre el uso de funciones lambda como el argumento clave en sorted() y más allá.

+4

explicación excelente y completa. Esta respuesta merece 100 puntos. Pero me pregunto por qué los me gusta son menos para esta respuesta. – javed

+2

Gracias por la explicación profunda. Yo [leer los documentos] (https://docs.python.org/3/library/functions.html#sorted) y ordenar cómo hacerlo y no estaba claro para mí la idea detrás de la función 'clave'. Si estás tratando de entender la función 'sorted', la sintaxis' lambda' se mete en el camino de la comprensión. – sanbor

+2

Esta es la mejor explicación aquí. Esto fue realmente útil para ayudarme a comprender cómo funcionó realmente esto. Comprendí la función lambda, pero usarla en el contexto de sorted() no tenía sentido. Esto realmente ayudó, gracias! – TGWaffles

Cuestiones relacionadas