funzione python max usando 'chiave' ed espressione lambda


182

Vengo da OOP e provo ad imparare il pitone. Sto usando la maxfunzione che utilizza un'espressione lambda per restituire l'istanza di tipo Playercon il massimo totalScorenell'elenco players.

def winner():
    w = max(players, key=lambda p: p.totalScore)

La funzione restituisce correttamente l'istanza di tipo Playercon il massimo totalScore. Sono confuso riguardo alle seguenti tre cose:

  1. Come funziona la maxfunzione? Quali sono gli argomenti che sta prendendo? Ho guardato la documentazione ma non ho capito.
  2. Qual è l'uso della parola chiave keynella funzione max? So che viene utilizzato anche nel contesto della sortfunzione
  3. Che cosa è l'espressione lambda? Come leggerli? Come funzionano?

Queste sono tutte domande concettuali molto noobish ma mi aiuteranno a capire la lingua. Sarebbe utile se potessi fornire esempi da spiegare. Grazie


Quale versione di Python?
charmlessCoin

2
Hai consultato la documentazione ?
Inbar Rose,

@charmlessCoin python 2.7.5
Vijay

2
@InbarRose Ho controllato la documentazione per la funzione max. Non l'ho capito davvero.
Vijay,

10
@InbarRose Questa pagina è attualmente il miglior risultato su Google per python max lambdae forse potrebbe effettivamente essere più utile per i nuovi utenti.
Mark

Risposte:


279

lambda è una funzione anonima, equivale a:

def func(p):
   return p.totalScore     

Ora maxdiventa:

max(players, key=func)

Ma poiché le defdichiarazioni sono istruzioni composte che non possono essere utilizzate dove è richiesta un'espressione, ecco perché a volte lambdavengono utilizzate.

Nota che lambdaequivale a quello che avresti inserito in una dichiarazione di reso di a def. Pertanto, non è possibile utilizzare le istruzioni all'interno di a lambda, sono consentite solo espressioni.


Cosa fa max?

max (a, b, c, ... [, key = func]) -> valore

Con un singolo argomento iterabile, restituisci il suo oggetto più grande. Con due o più argomenti, restituisce l'argomento più grande.

Quindi, restituisce semplicemente l'oggetto che è il più grande.


Come keyfunziona?

Per impostazione predefinita in Python 2 keyconfronta gli elementi in base a una serie di regole in base al tipo di oggetti (ad esempio una stringa è sempre maggiore di un numero intero).

Per modificare l'oggetto prima del confronto o per confrontare in base a un particolare attributo / indice, devi usare l' keyargomento.

Esempio 1:

Un semplice esempio, supponiamo di avere un elenco di numeri in forma di stringa, ma si desidera confrontare tali elementi con il loro valore intero.

>>> lis = ['1', '100', '111', '2']

Qui maxconfronta gli elementi usando i loro valori originali (le stringhe vengono confrontate lessicograficamente in modo da ottenere '2'come output):

>>> max(lis)
'2'

Per confrontare gli articoli in base al loro valore intero, utilizzare keycon un semplice lambda:

>>> max(lis, key=lambda x:int(x))  # compare `int` version of each item
'111'

Esempio 2: applicazione maxa un elenco di tuple.

>>> lis = [(1,'a'), (3,'c'), (4,'e'), (-1,'z')]

Per impostazione predefinita maxconfronterà gli articoli con il primo indice. Se il primo indice è lo stesso, confronterà il secondo indice. Come nel mio esempio, tutti gli articoli hanno un primo indice univoco, quindi otterresti questo come risposta:

>>> max(lis)
(4, 'e')

Ma cosa succede se si desidera confrontare ciascun elemento con il valore all'indice 1? Semplice: usare lambda:

>>> max(lis, key = lambda x: x[1])
(-1, 'z')

Confronto di elementi in un iterabile che contiene oggetti di diverso tipo :

Elenco con articoli misti:

lis = ['1','100','111','2', 2, 2.57]

In Python 2 è possibile confrontare elementi di due diversi tipi :

>>> max(lis)  # works in Python 2
'2'
>>> max(lis, key=lambda x: int(x))  # compare integer version of each item
'111'

Ma in Python 3 non puoi più farlo :

>>> lis = ['1', '100', '111', '2', 2, 2.57]
>>> max(lis)
Traceback (most recent call last):
  File "<ipython-input-2-0ce0a02693e4>", line 1, in <module>
    max(lis)
TypeError: unorderable types: int() > str()

Ma funziona, poiché stiamo confrontando la versione intera di ogni oggetto:

>>> max(lis, key=lambda x: int(x))  # or simply `max(lis, key=int)`
'111'

Penso che questo sia vecchio, ma avevo una domanda al riguardo. Vedo per la funzione lambda, la variabile xo i o qualsiasi altra cosa rappresenta sempre il valore di quell'indice nell'elenco. Questa iterazione viene eseguita dalla funzione max o dalla lambda? Le funzioni lambda ripetono sempre i possibili valori? Ad esempio: lengths = map(lambda word: len(word), words)dove words=['It', 'is', 'raining', 'cats', 'and', 'dogs']vedo che Lambda sta ripetendo ogni parola nell'elenco. Lo fa sempre?
Mo2,

1
@ Mo2 L' iterazione maxnon viene eseguita lambda( keyarg è facoltativo) e durante l'iterazione ogni elemento viene passato alla funzione specificata keye il valore restituito viene quindi utilizzato per il confronto.
Ashwini Chaudhary,

2
Solo per le persone che sono venute qui cercando su Google "parametro chiave max". max(lis, key=lambda x:int(x))può essere semplificato come max(lis, key=int). Python ha una funzione integrata, int (). Allo stesso modo è possibile utilizzare qualsiasi altra funzione integrata come keyargomento. Ad esempio, puoi ottenere la stringa più lunga lis=['a', 'aa', 'aaa']damax(lis, key=len)
GIOVANI

1
@YOUNG Possiamo usare qualsiasi funzione come argomento chiave non solo builtin funzioni, l'unica condizione è che la funzione dovrebbe accettare gli elementi che ha ricevuto dal max, min, sortedecc correttamente. Inoltre ho citato max(lis, key=int)proprio alla fine. :-)
Ashwini Chaudhary,

@Ashwini Chaudhary .. supponiamo che io abbia una lista come [1,2,3,4,5]. qui tutti gli articoli sono diversi. Sto usando la funzione data max (set (mylist), key = mylist.count) per trovare gli articoli più frequenti. poiché in questo caso non c'è nessun elemento che si ripete. sta restituendo l'articolo più basso. Possiamo fare qualcosa in modo che restituisca zero o null in tal caso.
Vikrant Rana,

12

Versione fortemente semplificata di max:

def max(items, key=lambda x: x):
    current = item[0]
    for item in items:
        if key(item) > key(current):
            current = item
    return current

Per quanto riguarda lambda:

>>> ident = lambda x: x
>>> ident(3)
3
>>> ident(5)
5

>>> times_two = lambda x: 2*x
>>> times_two(2)
4

10

Come funziona la funzione max?

Cerca l'elemento "più grande" in un iterabile. Suppongo che puoi cercare quello che è, ma in caso contrario, è qualcosa su cui puoi passare il ciclo, ad esempio un elenco o una stringa.

A che cosa serve la parola chiave nella funzione max? So che viene utilizzato anche nel contesto della funzione di ordinamento

Keyè una funzione lambda che dirà maxquali oggetti nell'iterabile sono più grandi di altri. Di 'se stavi ordinando qualche oggetto che hai creato tu stesso, e non qualcosa di ovvio, come numeri interi.

Che cosa è l'espressione lambda? Come leggerli? Come funzionano?

È una domanda più ampia. In parole povere, una lambda è una funzione che puoi passare in giro e farla usare ad altre parti di codice. Prendi questo per esempio:

def sum(a, b, f):
    return (f(a) + f(b))

Questo richiede due oggetti ae b, e una funzione f. Richiama f()ogni oggetto, quindi li somma insieme. Quindi guarda questa chiamata:

>>> sum(2, 2, lambda a:  a * 2)
8

sum()prende 2e chiama l'espressione lambda su di essa. Così f(a)diventa 2 * 2, che diventa 4. Lo fa quindi b, e aggiunge i due insieme.

In termini non così semplici, i lambda provengono dal calcolo lambda, che è l'idea di una funzione che restituisce una funzione; un concetto matematico molto interessante per esprimere il calcolo. Si può leggere su questo qui , e poi effettivamente capire che qui .

Probabilmente è meglio leggerlo un po 'di più, poiché i lambda possono essere fonte di confusione e non è immediatamente ovvio quanto siano utili. Controllare qui .


7

maxLa funzione viene utilizzata per ottenere il massimo da un iterable.

Gli iteratori possono essere elenchi, tuple, oggetti di dettatura, ecc. O persino oggetti personalizzati come nell'esempio fornito.

max(iterable[, key=func]) -> value
max(a, b, c, ...[, key=func]) -> value

With a single iterable argument, return its largest item.
With two or more arguments, return the largest argument.

Quindi, key=funcsostanzialmente ci consente di passare un argomento facoltativo keyalla funzione sulla base della quale vengono ordinati l'iteratore / argomenti forniti e viene restituito il massimo.

lambdaè una parola chiave python che funge da funzione pseudo. Quindi, quando gli passi un playeroggetto, tornerà player.totalScore. Pertanto, l'iterabile passato alla funzione maxverrà key ordinato in base al punteggio totale degli playeroggetti assegnati e restituirà il playervalore massimo di chi ha totalScore.

Se non keyviene fornito alcun argomento, viene restituito il massimo in base agli ordini Python predefiniti.

Esempi -

max(1, 3, 5, 7)
>>>7
max([1, 3, 5, 7])
>>>7

people = [('Barack', 'Obama'), ('Oprah', 'Winfrey'), ('Mahatma', 'Gandhi')]
max(people, key=lambda x: x[1])
>>>('Oprah', 'Winfrey')

6

Secondo la documentazione :

max (iterable [, chiave])
max (arg1, arg2, * args [, chiave])
Restituisce l'elemento più grande in un iterabile o il più grande di due o più argomenti.

Se viene fornito un argomento posizionale, iterable deve essere un iterable non vuoto (come una stringa non vuota, una tupla o un elenco). Viene restituito l'elemento più grande nell'iterabile. Se vengono forniti due o più argomenti posizionali, viene restituito il più grande degli argomenti posizionali.

L'argomento chiave opzionale specifica una funzione di ordinamento a un argomento come quella usata per list.sort (). L'argomento chiave, se fornito, deve essere in forma di parola chiave (ad esempio, max (a, b, c, key = func)).

Ciò che sta dicendo è che nel tuo caso, stai fornendo un elenco, in questo caso players. Quindi la maxfunzione eseguirà l'iterazione su tutti gli elementi nell'elenco e li confronterà tra loro per ottenere un "massimo".

Come puoi immaginare, con un oggetto complesso come playerdeterminare il suo valore per il confronto è complicato, quindi ti viene dato l' keyargomento per determinare come la maxfunzione deciderà il valore di ciascuno player. In questo caso, stai usando una funzione lambda per dire "per ciascuno pin playersget p.totalscoree usalo come suo valore per il confronto".


3

maxè incorporato nella funzione che accetta il primo argomento un iterable(come lista o tupla)

l'argomento della parola chiave keyha il suo valore predefinito Nonema accetta la funzione da valutare, consideralo come wrapper che valuta iterabile in base alla funzione

Considera questo dizionario di esempio:

d = {'aim':99, 'aid': 45, 'axe': 59, 'big': 9, 'short': 995, 'sin':12, 'sword':1, 'friend':1000, 'artwork':23}

Ex:

>>> max(d.keys())
'sword'

Come puoi vedere se passi l'iterabile solo senza kwarg (una funzione a key) restituisce il valore massimo della chiave (in ordine alfabetico)

Ex. Invece di trovare il valore massimo della chiave in ordine alfabetico, potrebbe essere necessario trovare la chiave massima per lunghezza della chiave:

>>>max(d.keys(), key=lambda x: len(x))
'artwork'

in questo esempio la funzione lambda sta restituendo la lunghezza della chiave che verrà ripetuta, quindi durante la valutazione dei valori invece di considerare in ordine alfabetico terrà traccia della lunghezza massima della chiave e restituirà la chiave che ha lunghezza massima

Ex.

>>> max(d.keys(), key=lambda x: d[x])
'friend'

in questo esempio la funzione lambda sta restituendo il valore della chiave del dizionario corrispondente che ha il valore massimo

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.