sort array python sorting lambda custom-function

array - sorted python 3



Sintaxis detrĂ¡s ordenada(clave=lambda:...) (6)

Como se solicitó el uso de lambda en el contexto de sorted() , échale un vistazo a este también https://wiki.python.org/moin/HowTo/Sorting/#Key_Functions

No entiendo muy bien la sintaxis detrás del argumento sorted() :

key=lambda variable: variable[0]

¿No es lambda arbitraria? ¿Por qué se dice la variable dos veces en lo que parece un dict ?


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á mi granito de arena.

En aras de la exhaustividad, 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. 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.

La sintaxis Lambda es la siguiente:

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

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

  1. La idea detrás del argumento clave es que incluye un conjunto de instrucciones que esencialmente apuntan a ''ordenado ()'' a qué elementos de la lista debe usar para ordenar. 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.

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] # ¿Tiene este resultado ordenado sentido intuitivo para usted?

Tenga en cuenta que mi función lambda indicó sorted 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 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, notará que, aunque las probabilidades vienen antes de los pares, los pares no están ordenados. ¿¿Por qué es esto?? Permite leer los documentos :

Funciones clave Comenzando con Python 2.4, list.sort () y sorted () agregaron un parámetro clave para especificar una función que se invocará en cada elemento de lista antes de realizar comparaciones.

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

¿Qué hace el ejemplo usando 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 algún lado. ¿Qué obtienes cuando clasificas la lista transformada?

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

Bueno, ahora sabemos por qué las probabilidades vienen antes de los pares. 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 Timsort ) utiliza un algoritmo de ordenació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 puede considerarse 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 una lista anidada, tupla, dict, etc., nuevamente determinado por la función lambda.

Tratemos de 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])

Mis métodos ordenados obviamente dicen: "Por favor, ordena esta lista". El argumento clave hace que sea un poco más específico diciendo, para cada elemento (x) en mylist, regrese el índice 1 de ese elemento, luego clasifique 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. Entonces obtenemos:

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

Ejecuta 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" tu intuición sobre el uso de las funciones lambda como argumento clave en sorted () y más allá.


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

Significa casi exactamente lo mismo que:

def some_method(variable): return variable[0]


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 la key debe ser algo que se puede llamar.

El uso de lambda crea una función anónima (que es invocable). En el caso de sorted el invocable solo toma un parámetro. La lambda de Python 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 de 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 otros constructos 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 solo 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 mano izquierda del colon es el nombre de un parámetro y en el lado derecho se usa en el bloque de código para calcular algo.


lambda es una función anónima, no 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.