No entiendo muy bien la sintaxis detrás del sorted()
argumento:
key=lambda variable: variable[0]
¿No es lambda
arbitrario? ¿Por qué se variable
indica dos veces en lo que parece un dict
?
No entiendo muy bien la sintaxis detrás del sorted()
argumento:
key=lambda variable: variable[0]
¿No es lambda
arbitrario? ¿Por qué se variable
indica dos veces en lo que parece un dict
?
Respuestas:
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 invocable.
El uso de lambda
crea una función anónima (que es invocable). En el caso del sorted
invocable solo toma un parámetro. Python 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 pitón, así como while
, for
, if
y así sucesivamente. Todas son 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 simplemente nos da una forma de hacerlo 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 el lado izquierdo del colon es el nombre de un parámetro y en el lado derecho se está usando en el bloque de código para calcular algo.
Creo que todas las respuestas aquí cubren el núcleo de lo que hace la función lambda en el contexto de sorted () bastante bien, sin embargo, todavía siento que falta una descripción que conduzca a una comprensión intuitiva, así que aquí están mis dos centavos.
En aras de la exhaustividad, declararé 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.
La sintaxis de Lambda es la siguiente:
lambda input_variable (s) : sabroso one liner
p.ej
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
In [4]: (lambda x, y: x / y)(10, 2)
Out[4]: 5.0
In [5]: (lambda: 'amazing lambda')() # func with no args!
Out[5]: 'amazing lambda'
key
argumento es que debe tomar un conjunto de instrucciones que esencialmente apuntará la función 'sorted ()' en los elementos de la lista que deben usarse para ordenar. Cuando dice key=
, 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 el argumento clave y usarlo para crear una lista transformada que me informará sobre el orden de la lista ordenada final.Echale un vistazo:
mylist = [3,6,3,2,4,8,23]
sorted(mylist, key=WhatToSortBy)
Ejemplo 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] # ¿Te resulta intuitivo este resultado ordenado?
Tenga en cuenta que mi función lambda dijo ordenado para verificar si (e) era par o impar antes de ordenar.
¡PERO ESPERA! Puede (o quizás debería) preguntarse dos cosas: primero, ¿por qué mis probabilidades están antes de mis pares? (Ya que mi valor clave parece estar diciéndole a mi función ordenada que priorice los pares usando el operador mod x%2==0
) Segundo, ¿por qué mis pares están fuera de servicio? 2 viene antes que 6 ¿verdad? Al analizar este resultado, aprenderemos algo más profundo sobre cómo funciona el argumento sorted ('key'), especialmente en conjunción con la función lambda anónima.
En primer lugar, notará que si bien las probabilidades se presentan antes de las igualaciones, las mismas no están ordenadas. ¿¿Por qué es esto?? Leamos los documentos :
Funciones clave A partir de Python 2.4, list.sort () y sorted () agregaron un parámetro clave para especificar una función que se invocará en cada elemento de la lista antes de realizar comparaciones.
Aquí tenemos que leer un poco entre líneas, 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, clasificamos por el valor al que nos señala la función clave.
Entonces, ¿qué devuelve el ejemplo con un módulo? Un valor booleano: True == 1
, False == 0
. Entonces, ¿cómo se soluciona ordenado 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 ordenas la lista transformada?
[0,0,0,1,1,1,1]
Bien, ahora sabemos por qué las probabilidades se presentan antes de los pares. Pero la siguiente pregunta es: ¿por qué el 6 todavía aparece antes que el 2 en mi lista final? Bueno, eso es fácil, ¡es porque la clasificación solo ocurre una vez! es decir, esos 1 todavía representan los valores de la lista original, que están en sus posiciones originales entre sí. Dado que la ordenación solo ocurre una vez, y no llamamos a ningún tipo de función de ordenación para ordenar los valores pares originales de menor a mayor, esos valores permanecen en su orden original entre sí.
La pregunta final es esta: ¿Cómo pienso conceptualmente acerca de cómo el orden de mis valores booleanos se transforma de nuevo en los valores originales cuando imprimo la lista ordenada final?
Sorted () es un método incorporado que (hecho curioso ) utiliza un algoritmo de clasificación híbrido llamado Timsortque combina aspectos de clasificación de fusión y clasificación de inserción. Me parece claro que cuando lo llamas, hay una mecánica que guarda 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, si bien está organizada por Odds and Evens, no está ordenada por sublista (las evens en este caso están fuera de servicio). El hecho de que las probabilidades estén ordenadas es porque ya estaban ordenadas por coincidencia en la lista original. La conclusión de todo esto es que cuando lambda hace esa transformación, se conserva el orden original de las sublistas.
Entonces, ¿cómo se relaciona todo esto con la pregunta original y, lo que es más importante, nuestra intuición sobre cómo debemos implementar sorted () con su argumento clave y lambda?
Esa función lambda puede considerarse como un puntero que apunta a los valores que debemos clasificar, ya sea un puntero que asigna un valor a su valor booleano transformado por la función lambda, o si es un elemento particular en una lista anidada, tupla, dict, etc., nuevamente determinado por la función lambda.
Vamos a intentar y predecir 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])
Mi sorted
llamada obviamente dice: "Por favor ordene esta lista". El argumento clave lo hace un poco más específico al decir que, para cada elemento (x) en mylist, devuelva el índice 1 de ese elemento, luego ordene todos los elementos de la lista original 'mylist' por el orden ordenado de la lista calculado por La función lambda. Como tenemos una lista de tuplas, podemos devolver un elemento indexado de esa tupla. Entonces obtenemos:
[(6, 2, 8), (3, 5, 8), (6, 8, 5), (2, 9, 4)]
Ejecute ese código y verá que este es el orden. Intente indexar una lista de enteros y verá 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 argumento clave en sorted () y más allá.
key
función. Si está tratando de entender la sorted
función, la lambda
sintaxis simplemente se interpone en el camino de la comprensión.
lambda
es una palabra clave de Python que se usa para generar funciones anónimas .
>>> (lambda x: x+2)(3)
5
3
porque se pasa 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)
, lo que no es válido ya 2
que no es una función.
Un ejemplo más de uso de la función sorted () con key = lambda. Consideremos que tienes una lista de tuplas. En cada tupla tiene una marca, modelo y peso del automóvil y desea ordenar esta lista de tuplas por marca, modelo o peso. Puedes hacerlo con lambda.
cars = [('citroen', 'xsara', 1100), ('lincoln', 'navigator', 2000), ('bmw', 'x5', 1700)]
print(sorted(cars, key=lambda car: car[0]))
print(sorted(cars, key=lambda car: car[1]))
print(sorted(cars, key=lambda car: car[2]))
Resultados:
[('bmw', 'x5', '1700'), ('citroen', 'xsara', 1100), ('lincoln', 'navigator', 2000)]
[('lincoln', 'navigator', 2000), ('bmw', 'x5', '1700'), ('citroen', 'xsara', 1100)]
[('citroen', 'xsara', 1100), ('bmw', 'x5', 1700), ('lincoln', 'navigator', 2000)]
Dado que se solicitó el uso de lambda en el contexto de sorted()
, eche un vistazo a esto también https://wiki.python.org/moin/HowTo/Sorting/#Key_Functions
Solo para reformular, la tecla (Opcional. Una función a ejecutar para decidir el orden. El valor predeterminado es Ninguno) en las funciones ordenadas espera una función y usted usa lambda.
Para definir lambda, especifique la propiedad del objeto que desea ordenar y la función ordenada incorporada de Python se encargará automáticamente de ello.
Si desea ordenar por varias propiedades, asigne key = lambda x: (propiedad1, propiedad2).
Para especificar el orden, pase reverse = true como tercer argumento (Opcional. Un booleano. False ordenará ascendente, True ordenará descendente. El valor predeterminado es False) de la función ordenada.
Respuesta simple y que no requiere mucho tiempo con un ejemplo relevante a la pregunta formulada Siga este ejemplo:
user = [{"name": "Dough", "age": 55},
{"name": "Ben", "age": 44},
{"name": "Citrus", "age": 33},
{"name": "Abdullah", "age":22},
]
print(sorted(user, key=lambda el: el["name"]))
print(sorted(user, key= lambda y: y["age"]))
Mire los nombres en la lista, comienzan con D, B, C y A. Y si nota las edades, son 55, 44, 33 y 22. El primer código impreso
print(sorted(user, key=lambda el: el["name"]))
Resultados a:
[{'name': 'Abdullah', 'age': 22},
{'name': 'Ben', 'age': 44},
{'name': 'Citrus', 'age': 33},
{'name': 'Dough', 'age': 55}]
ordena el nombre, porque por clave = lambda el: el ["nombre"] estamos ordenando los nombres y los nombres regresan en orden alfabético.
El segundo código de impresión
print(sorted(user, key= lambda y: y["age"]))
Resultado:
[{'name': 'Abdullah', 'age': 22},
{'name': 'Citrus', 'age': 33},
{'name': 'Ben', 'age': 44},
{'name': 'Dough', 'age': 55}]
ordena por edad y, por lo tanto, la lista vuelve por orden ascendente de edad.
Pruebe este código para una mejor comprensión.
def
.