Non capisco bene la sintassi dietro l' sorted()
argomento:
key=lambda variable: variable[0]
Non è lambda
arbitrario? Perché è variable
indicato due volte in quello che sembra un dict
?
Non capisco bene la sintassi dietro l' sorted()
argomento:
key=lambda variable: variable[0]
Non è lambda
arbitrario? Perché è variable
indicato due volte in quello che sembra un dict
?
Risposte:
key
è una funzione che verrà chiamata per trasformare gli oggetti della collezione prima che vengano confrontati. Il parametro passato a key
deve essere qualcosa che è richiamabile.
L'uso di lambda
crea una funzione anonima (che è richiamabile). Nel caso del sorted
callable accetta solo un parametro. Python's lambda
è piuttosto semplice. Può solo fare e restituire davvero una cosa.
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 dai 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 confrontare l'uso di lambda con quello di def per 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. Il che lo rende ideale per l'utilizzo come parametro di una funzione.
variable
viene usato due volte qui perché sulla sinistra dei due punti è il nome di un parametro e sulla destra viene utilizzato nel blocco di codice per calcolare qualcosa.
Penso che tutte le risposte qui coprano il nucleo di ciò che la funzione lambda fa nel contesto di sort () abbastanza bene, tuttavia mi sento ancora come se mancasse una descrizione che porta a una comprensione intuitiva, quindi ecco i miei due centesimi.
Per completezza, indicherò l'evidente in primo piano: sort () restituisce un elenco di elementi ordinati e se vogliamo ordinare in un modo particolare o se vogliamo ordinare un elenco complesso di elementi (ad esempio elenchi nidificati o un elenco di tuple) possiamo invocare l'argomento chiave.
Per me, la comprensione intuitiva dell'argomento chiave, il motivo per cui deve essere richiamabile e l'uso di lambda come funzione (anonima) richiamabile per ottenere questo risultato si divide in due parti.
La sintassi Lambda è la seguente:
lambda input_variable (s) : gustoso one liner
per 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
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
dell'argomento è che dovrebbe includere una serie di istruzioni che indicheranno essenzialmente la funzione 'sort ()' su quegli elementi della lista che dovrebbero essere usati per ordinare. Quando dice key=
, ciò che significa in realtà è: mentre eseguo iterando l'elenco un elemento alla volta (cioè per e in list), passerò l'elemento corrente alla funzione che fornisco nell'argomento chiave e lo uso per creare un elenco trasformato che mi informerà sull'ordine dell'elenco ordinato finale.Controlla:
mylist = [3,6,3,2,4,8,23]
sorted(mylist, key=WhatToSortBy)
Esempio di 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 ha un senso intuitivo per te?
Si noti che la mia funzione lambda ha detto a ordinati per verificare se (e) era pari o dispari prima dell'ordinamento.
MA ASPETTA! Potresti (o forse dovresti) chiederti 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 dare la priorità ai pari usando l'operatore mod in x%2==0
). Secondo, perché i miei pari sono fuori servizio? 2 viene prima di 6 giusto? Analizzando questo risultato, impareremo qualcosa di più approfondito su come funziona l'argomento ordinato () 'chiave', specialmente in combinazione con la funzione lambda anonima.
In primo luogo, noterai che mentre le probabilità vengono prima dei pari, i pari stessi non vengono ordinati. Perchè è questo?? Consente di leggere i documenti :
Funzioni chiave A partire da Python 2.4, sia list.sort () che sort () hanno aggiunto un parametro chiave per specificare una funzione da chiamare su ciascun elemento della lista prima di effettuare i confronti.
Dobbiamo fare un po 'di lettura tra le righe qui, ma ciò che ci dice è che la funzione di ordinamento viene chiamata solo una volta, e se specificiamo l'argomento chiave, allora ordiniamo per il valore a cui punta la funzione chiave.
Quindi cosa restituisce l'esempio usando un modulo? Un valore booleano: True == 1
, False == 0
. Quindi, come funziona l'ordinamento con questa chiave? Trasforma sostanzialmente l'elenco originale in una sequenza di 1 e 0 secondi.
[3,6,3,2,4,8,23] diventa [0,1,0,1,1,1,0]
Ora stiamo arrivando da qualche parte. Cosa ottieni quando ordini l'elenco trasformato?
[0,0,0,1,1,1,1]
Va bene, quindi ora sappiamo perché le probabilità arrivano prima dei pari. Ma la domanda successiva è: perché il 6 viene ancora prima del 2 nella mia lista finale? Bene, è facile - è perché l'ordinamento avviene solo una volta! cioè Quelli 1 rappresentano ancora i valori della lista originale, che sono nelle loro posizioni originali l'uno rispetto all'altro. Poiché l'ordinamento avviene una sola volta e non chiamiamo alcun tipo di funzione di ordinamento per ordinare i valori pari originali dal più basso al più alto, tali valori rimangono nel loro ordine originale l'uno rispetto all'altro.
La domanda finale è quindi questa: come posso pensare concettualmente a come l'ordine dei miei valori booleani viene ricondotto ai valori originali quando stampo l'elenco ordinato finale?
Sorted () è un metodo integrato che (fatto divertente) utilizza un algoritmo di ordinamento ibrido chiamato Timsortche combina aspetti di tipo di unione e ordinamento per inserzione. Mi sembra chiaro che quando lo chiami, c'è un meccanico che tiene in memoria questi valori e li raggruppa con la loro identità booleana (maschera) determinata dalla (...!) Funzione lambda. L'ordine è determinato dalla loro identità booleana calcolata dalla funzione lambda, ma tieni presente che queste liste secondarie (di uno e di zeri) non sono esse stesse ordinate in base ai loro valori originali. Quindi, l'elenco finale, sebbene organizzato da Odds e Evens, non è ordinato in base alla sublist (in questo caso i pari sono fuori servizio). Il fatto che le probabilità siano ordinate è perché erano già in ordine per coincidenza nell'elenco originale. L'aspetto da asporto di tutto ciò è che quando lambda esegue quella trasformazione, l'ordine originale delle liste secondarie viene mantenuto.
Quindi, in che modo tutto ciò si ricollega alla domanda originale e, soprattutto, alla 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 elemento particolare in un elenco nidificato, tupla, dict, ecc., ancora una volta determinato dalla funzione lambda.
Proviamo a 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])
La mia sorted
chiamata ovviamente dice "Per favore ordina questo elenco". L'argomento chiave lo 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 'in base all'ordine ordinato dell'elenco calcolato da la funzione lambda. Poiché abbiamo un elenco di tuple, possiamo restituire un elemento indicizzato da quella tupla. Quindi otteniamo:
[(6, 2, 8), (3, 5, 8), (6, 8, 5), (2, 9, 4)]
Esegui quel codice e scoprirai che questo è l'ordine. Prova a indicizzare un elenco di numeri interi e scoprirai che il codice si rompe.
Questa è stata una spiegazione lunga, ma spero che questo aiuti a "ordinare" la tua intuizione sull'uso delle funzioni lambda come argomento chiave in sort () e oltre.
key
funzione. Se stai cercando di capire la sorted
funzione, la lambda
sintassi si limita a capire.
lambda
è una parola chiave Python utilizzata per generare funzioni anonime .
>>> (lambda x: x+2)(3)
5
3
perché viene passato a una funzione. Le parentesi sono attorno alla lambda in modo che l'espressione non venga analizzata lambda x: x+2(3)
, il che non è valido poiché 2
non è una funzione.
Un altro esempio di utilizzo dell'ordinamento () funzione con key = lambda. Consideriamo che hai un elenco di tuple. In ogni tupla hai una marca, un modello e un peso dell'auto e vuoi ordinare questo elenco di tuple per marca, modello o peso. Puoi farlo 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]))
risultati:
[('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)]
Poiché l'uso di lambda è stato richiesto nel contesto di sorted()
, dai un'occhiata anche a questo https://wiki.python.org/moin/HowTo/Sorting/#Key_Functions
Solo per riformulare, il tasto (Opzionale. Una funzione da eseguire per decidere l'ordine. L'impostazione predefinita è Nessuno) nelle funzioni ordinate si aspetta una funzione e si utilizza lambda.
Per definire lambda, si specifica la proprietà dell'oggetto che si desidera ordinare e la funzione ordinata integrata di Python se ne occuperà automaticamente.
Se si desidera ordinare in base a più proprietà, assegnare key = lambda x: (proprietà1, proprietà2).
Per specificare l'ordinamento, passare reverse = true come terzo argomento (Facoltativo. Un valore booleano. False ordinerà in ordine crescente, True ordinerà in ordine decrescente. L'impostazione predefinita è False) della funzione ordinata.
Risposta semplice e non dispendiosa in termini di tempo con un esempio pertinente alla domanda posta Seguire questo esempio:
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"]))
Guarda i nomi nell'elenco, iniziano con D, B, C e A. E se noti le età, sono 55, 44, 33 e 22. Il primo codice di stampa
print(sorted(user, key=lambda el: el["name"]))
Risultati a:
[{'name': 'Abdullah', 'age': 22},
{'name': 'Ben', 'age': 44},
{'name': 'Citrus', 'age': 33},
{'name': 'Dough', 'age': 55}]
ordina il nome, perché con key = lambda el: el ["name"] stiamo ordinando i nomi e i nomi ritornano in ordine alfabetico.
Il secondo codice di stampa
print(sorted(user, key= lambda y: y["age"]))
Risultato:
[{'name': 'Abdullah', 'age': 22},
{'name': 'Citrus', 'age': 33},
{'name': 'Ben', 'age': 44},
{'name': 'Dough', 'age': 55}]
ordina per età, e quindi l'elenco ritorna in ordine crescente di età.
Prova questo codice per una migliore comprensione.
def
.