2012-01-23 11 views

risposta

105

key è una funzione che sarà chiamata a trasformare gli elementi della collezione prima di essere confrontati. Il parametro passato a key deve essere qualcosa che può essere richiamato.

L'uso di lambda crea una funzione anonima (che è callable). Nel caso di sorted il callable accetta solo un parametro. Python lambda è piuttosto semplice. Può solo fare e restituire una cosa in realtà.

La sintassi di lambda è la parola lambda seguita dall'elenco dei nomi dei parametri quindi da un singolo blocco di codice. L'elenco dei parametri e il blocco di codice sono delineati da due punti. Questo è simile ad altri costrutti in pitone così come while, for, if e così via. Sono tutte istruzioni che in genere hanno un blocco di codice. Lambda è solo un'altra istanza di un'istruzione con un blocco di codice.

Possiamo paragonare l'uso di lambda con quella del def di creare una funzione.

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

lambda ci dà solo un modo per farlo senza assegnare un nome. Ciò lo rende ottimo per l'utilizzo come parametro di una funzione.

variable viene utilizzato due volte qui perché sul lato sinistro del colon è il nome di un parametro e sul lato destro viene utilizzato nel blocco di codice per calcolare qualcosa.

+7

note (a OP): dovrebbe essere evitato di assegnare un lambda a un nome (cioè utilizzarlo in modo diverso da come funzione anonima). se ti ritrovi a fare questo probabilmente dovresti semplicemente usare un 'def'. – wim

24

lambda è una parola chiave di Python che viene utilizzato per generate anonymous functions.

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

Perché ci sono parentesi attorno a ciascuna? –

+16

I paren sono intorno a '3' perché è passato a una funzione. I parens sono intorno al lambda in modo che l'espressione non venga analizzata come 'lambda x: x + 2 (3)', che non è valida poiché '2' non è una funzione. –

10

La variable sinistra del : è un nome di parametro. L'uso di variable sulla destra sta facendo uso del parametro.

Mezzi quasi esattamente la stessa:

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

lambda è una funzione anonima, non una funzione arbitraria. Il parametro accettato è la variabile con cui stai lavorando e la colonna in cui lo stai ordinando.

41

Credo che tutte le risposte qui coprire il nucleo di ciò che la funzione lambda fa nel contesto ordinato() abbastanza bene, tuttavia mi sento ancora come una descrizione che porta a una comprensione intuitiva è carente, quindi ecco i miei due centesimi.

Per completezza, premetto l'ovvio fronte: sort() restituisce un elenco di elementi ordinati e se vogliamo ordinare in un modo particolare o se vogliamo ordinare un elenco complesso di elementi (es. liste annidate o un elenco di tuple) possiamo invocare l'argomento chiave.

Per me, la comprensione intuitiva dell'argomento chiave, perché deve essere richiamabile, e l'uso di lambda come funzione (anonima) chiamabile per ottenere questo viene in due parti.

  1. L'uso di lamba in ultima analisi significa che non è necessario scrivere (definire) un'intera funzione, come quella di cui è stato fornito un esempio di sblom. Le funzioni Lambda vengono create, utilizzate e immediatamente distrutte, in modo che non creino il codice con più codice che verrà utilizzato una sola volta. Questo, a quanto ho capito, è l'utilità principale della funzione lambda e le sue applicazioni per tali ruoli sono ampie. La sua sintassi è puramente per convenzione, che è in sostanza la natura della sintassi programmatica in generale. Impara la sintassi e fallo.

sintassi Lambda è la seguente:

lambda input_variable (s): gustoso uno fodera

esempio

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. L'idea dietro l'argomento chiave è che ci vuole in un insieme di istruzioni che essenzialmente Point 'ordinato()' in cui la lista elementi si dovrebbe utilizzare per l'ordinamento. Quando dice "chiave =", ciò che significa realmente è: mentre iterò attraverso l'elenco un elemento alla volta (cioè per e in lista), passerò l'elemento corrente alla funzione che fornisco nella chiave argomento e usarlo per creare una lista trasformata che mi informerà sull'ordine della lista ordinata finale.

Check it out: esempio

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

Base:

sorted(mylist) 

[2, 3, 3, 4, 6, 8, 23] # tutti i numeri sono in ordine da piccolo a grande.

Esempio 1:

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

[3, 3, 23, 6, 2, 4, 8] # Questo risultato ordinato senso intuitivo per te?

Si noti che la funzione lambda veniva ordinata per verificare se (e) era pari o dispari prima dell'ordinamento.

MA ASPETTARE! Potresti (o forse dovresti) chiedermi due cose: in primo luogo, perché le mie probabilità vengono prima dei miei pari (dal momento che il mio valore chiave sembra dire alla mia funzione ordinata di assegnare priorità a evens usando l'operatore mod in x% 2 == 0) e in secondo luogo, perché i miei amici sono fuori uso? 2 arriva prima delle 6, giusto? Analizzando questo risultato, impareremo qualcosa di più profondo su come funziona l'argomento 'chiave' ordinato(), specialmente in combinazione con la funzione lambda anonima.

In primo luogo, noterete che mentre le probabilità vengono prima degli eventi, gli stessi eventi non sono ordinati. Perchè è questo??Lets read the docs:

Funzioni chiave A partire da Python 2.4, sia list.sort() e ordinate() ha aggiunto un parametro chiave per specificare una funzione da chiamare sul ogni elemento della lista prima di fare paragoni.

Dobbiamo fare un po 'di lettura tra le righe qui, ma ciò che questo ci dice è che la funzione di ordinamento viene chiamata solo una volta, e se specifichiamo l'argomento chiave, quindi ordiniamo per il valore che la funzione chiave ci indica

Cosa restituisce l'esempio utilizzando un modulo? Un valore booleano: True = 1, False = 0. Quindi, come viene risolto il problema con questa chiave? Converte basicamente la lista originale in una sequenza di 1 e 0.

[3,6,3,2,4,8,23] diventa [0,1,0,1,1,1,0]

Ora stiamo ottenendo da qualche parte. Cosa ottieni quando ordini la lista trasformata?

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

Bene, ora sappiamo perché le probabilità vengono prima le dispari. Ma la prossima domanda è: perché i 6 vengono ancora prima dei 2 nella mia lista finale? Bene, è facile - è perché l'ordinamento avviene solo una volta! La domanda finale è quindi questa: come penso concettualmente su come l'ordine dei miei valori booleani viene trasformato di nuovo nei valori originali quando stampo la lista ordinata finale?

Sorted() è un metodo incorporato che (fun fact) utilizza un algoritmo di ordinamento ibrido chiamato Timsort che combina aspetti dell'ordinamento di unione e ordinamento di inserimento. Mi sembra chiaro che quando lo chiami, c'è un meccanico che tiene in memoria questi valori e li impacchetta con la loro identità booleana (maschera) determinata da (...!) La funzione lambda. L'ordine è determinato dalla loro identità booleana calcolata dalla funzione lambda, ma si tenga presente che questi sottolisti (di uno e zero) non sono ordinati in base ai loro valori originali. Quindi, la lista finale, sebbene organizzata da Odds and Evens, non è ordinata per sottolista (gli altri in questo caso sono fuori uso). Il fatto che le quote siano ordinate è perché erano già in ordine per coincidenza nell'elenco originale. Da tutto questo deriva che quando lambda esegue questa trasformazione, l'ordine originale delle sottoliste viene mantenuto.

Quindi, come tutto questo si ricollega alla domanda originale e, cosa più importante, la nostra intuizione su come dovremmo implementare sort() con il suo argomento chiave e lambda?

Quella funzione lambda può essere pensata come un puntatore che punta ai valori che dobbiamo ordinare, sia che si tratti di un puntatore che mappa un valore al suo booleano trasformato dalla funzione lambda, sia che sia un particolare elemento in un nidificato lista, tupla, dict, ecc. nuovamente determinata dalla funzione lambda.

Consente di provare e prevedere cosa succede quando eseguo il seguente codice.

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

I miei metodi ordinati ovviamente dicono "Si prega di ordinare questo elenco". L'argomento chiave rende un po 'più specifico dicendo, per ogni elemento (x) in mylist, restituire l'indice 1 di quell'elemento, quindi ordinare tutti gli elementi dell'elenco originale' mylist 'dall'ordine ordinato dell'elenco calcolato da la funzione lambda.Dato che abbiamo una lista di tuple, possiamo restituire un elemento indicizzato da quella tupla. Così otteniamo:

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

Run quel codice, e scoprirai che questo è l'ordine. Prova a indicizzare un elenco di numeri interi e scoprirai che il codice si interrompe.

Questa è stata una spiegazione a lungo termine, ma spero che questo aiuti a "ordinare" l'intuizione sull'uso delle funzioni lambda come argomento chiave in Sort() e oltre.

+4

spiegazione eccellente e completa. Questa risposta merita 100 punti. Ma mi chiedo perché i Mi piace siano meno di questa risposta. – javed

+2

Grazie per la spiegazione profonda. Io [leggi i documenti] (https://docs.python.org/3/library/functions.html#sorted) e l'ordinamento delle istruzioni e non mi era chiaro l'idea alla base della funzione 'chiave'. Se stai cercando di capire la funzione 'sorted', loro la sintassi' lambda' si avvicina alla comprensione. – sanbor

+2

Questa è la migliore spiegazione qui. Questo è stato davvero utile per aiutarmi a capire come ha funzionato in realtà - ho afferrato la funzione lambda, ma usarla nel contesto di Sort() non aveva senso. Questo mi ha davvero aiutato, grazie! – TGWaffles

Problemi correlati