2013-08-18 8 views
97

Vengo dallo sfondo di OOP e provo ad imparare python. Sto usando la funzione max che utilizza un'espressione lambda per restituire l'istanza di tipo Player avente massima totalScore nella lista players.python max function usando 'key' e espressione lambda

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

La funzione restituisce correttamente un'istanza di tipo Player avente massima totalScore. Sono confuso circa le seguenti tre cose:

  1. Come funziona il max funzione? Quali sono gli argomenti che sta prendendo? Ho guardato la documentazione ma non ho capito.
  2. A cosa serve la parola chiave key nella funzione massima? So che viene utilizzato anche nel contesto della funzione sort
  3. Significato dell'espressione lambda? Come leggerli? Come funzionano?

Queste sono tutte domande molto noobiche concettuali, ma mi aiuteranno a capire la lingua. Sarebbe d'aiuto se potessi fornire degli esempi da spiegare. Grazie

+0

Quale versione di Python? – charmlessCoin

+0

Hai consultato la [documentazione] (http://docs.python.org/2/library/functions.html#max)? –

+0

@charmlessCoin python 2.7.5 – Vijay

risposta

150

lambda è una funzione anonima, è equivalente a:

def func(p): 
    return p.totalScore  

Ora max diventa:

max(players, key=func) 

Ma, come def dichiarazioni sono dichiarazioni composti non possono essere utilizzati in cui l'espressione è richiesto, ecco perché a volte vengono usati gli lambda.

Si noti che lambda è equivalente a ciò che si inseriva in un estratto conto di def. Pertanto, non è possibile utilizzare le istruzioni all'interno di lambda, sono consentite solo le espressioni.


Cosa fa max?

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

Con il singolo argomento iterabile, restituisce il suo più grande voce. Con due o altri argomenti, restituisce l'argomento più grande.

Quindi restituisce semplicemente l'oggetto più grande.


How `key` works? 

Per default in chiave pitone 2 confronta elementi in base a un set of rules base al tipo di oggetti (per esempio una stringa è sempre maggiore di un numero intero).

Per modificare l'oggetto prima del confronto o confrontare in base a un determinato attributo/indice, è necessario utilizzare l'argomento key.

Esempio 1:

Un semplice esempio, supponiamo che avete un elenco di numeri in forma di stringa, ma si vuole confrontare gli elementi dal loro valore intero.

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

Qui max confronta gli oggetti utilizzando i loro valori originali (stringhe vengono confrontate lessicografico modo si otterrebbe '2' come output):

>>> max(lis) 
'2' 

Per confrontare gli oggetti dal loro utilizzo chiave valore intero con un semplice lambda:

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

Esempio 2: Applicazione max ad una lista di liste.

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

Per impostazione predefinita max si confronterà le voci dal primo indice, se il primo indice è lo stesso allora sarebbe confrontare il secondo indice.Come nel mio esempio tutti gli elementi hanno unico primo indice in modo, si otterrebbe questo come la risposta:

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

Ma, cosa succede se si voleva confrontare ogni elemento per il valore di indice 1? Semplice, utilizzare lambda:

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

Confrontando gli elementi in un iterabile che contiene oggetti di diverso tipo:

elenco con gli articoli misti:

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

In Python 2 it is possible to compare items of two different types:

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

But in Python 3 you can't do that any more:

>>> 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 questo funziona, come stiamo confrontando la versione intera di ogni oggetto:

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

Penso che sia vecchio, ma avevo una domanda riguardo a questo. Vedo per la funzione lambda, la variabile x o i o qualsiasi altra cosa rappresenta sempre il valore di quell'indice nella lista. Questa iterazione è eseguita dalla funzione max o dal lambda? Le funzioni lambda eseguono sempre iterazioni sui valori possibili? Ad esempio: 'lengths = map (parola lambda: len (word), words)' dove 'words = ['It', 'is', 'rain', 'cats', 'and', 'dogs']' I vedi che lambda sta iterando su ogni parola nella lista. Lo fa sempre? – Mo2

+1

@ Mo2 L'iterazione viene eseguita da 'max' non' lambda' ('key' arg è facoltativo) e durante l'iterazione ogni elemento viene passato alla funzione specificata in' key' e il valore restituito viene quindi utilizzato per il confronto. –

+1

Solo per le persone che sono venute qui su google "max key parameter". 'max (lis, key = lambda x: int (x))' può essere semplificato come 'max (lis, key = int)'. Python ha una funzione built-in, int(). Allo stesso modo puoi usare qualsiasi altra funzione built-in come argomento 'key'. Ad esempio puoi ottenere la stringa più lunga da 'lis = ['a', 'aa', 'aaa']' da 'max (lis, key = len)' – YOUNG

8

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 

quanto riguarda lambda:

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

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

Secondo la documentation:

max (iterable [, chiave])
max (arg1, arg2, * args [, chiave])
ritorno del più grande elemento in un iterabile o il più grande dei due o più argomenti.

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

L'argomento chiave opzionale specifica una funzione di ordinamento a un argomento simile a quella utilizzata 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 funzione max eseguirà iterazioni su tutti gli elementi nell'elenco e li confronta tra loro per ottenere un "massimo".

Come si può immaginare, con un oggetto complesso come un player determinare il suo valore per il confronto è difficile, quindi si è dato l'argomento key per determinare come la funzione max deciderà il valore di ogni player.In questo caso, si sta utilizzando una funzione lambda per dire "per ogni p in players ottenere p.totalscore e utilizzarlo come valore per il confronto".

8

Come funziona il lavoro di funzione max?

Cerca l'elemento "più grande" in un iterabile. Immagino che tu sia il a cercare di capire cosa sia, ma in caso contrario, è qualcosa che puoi ricominciare da capo, cioè un elenco o una stringa.

A cosa serve la chiave della parola chiave nella funzione massima? So che è utilizzato anche in un contesto di funzione di ordinamento

Key è una funzione lambda che dirà max quali oggetti nella iterabile sono più grandi di altri. Dì se stavi ordinando qualche oggetto che hai creato tu stesso, e non qualcosa di ovvio, come interi.

Significato dell'espressione lambda? Come leggerli? Come funzionano?

Questa è una specie di domanda più ampia. In termini semplici, una lambda è una funzione che è possibile passare intorno a e utilizzare altri pezzi di codice. Prendete questo esempio:

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

questo richiede due oggetti, a e b, e una funzione di f. Chiama f() su ciascun oggetto, quindi li aggiunge insieme. Così un'occhiata a questa chiamata:

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

sum() prende 2, e chiede l'espressione lambda su di esso. Quindi, f(a) diventa 2 * 2, che diventa 4. Quindi lo fa per b e aggiunge i due insieme.

In termini non molto semplici, i lambda derivano dal lambda calcolo, che è l'idea di una funzione che restituisce una funzione; un concetto matematico molto interessante per esprimere il calcolo. È possibile leggere su tale here e quindi in realtà comprendere it here.

Probabilmente è meglio leggerlo un po 'di più, dato che lambda può essere fonte di confusione e non è immediatamente evidente quanto siano utili. Controllare here.

3

max la funzione viene utilizzata per ottenere il massimo da un iterable.

Gli iteratori possono essere liste, tuple, oggetti dict, ecc. O anche oggetti personalizzati come nell'esempio che hai 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. 

Così, il key=func ci permette in sostanza di passare un argomento opzionale key alla funzione sulla cui base il dato iteratore/argomenti sono allineati & la massima viene restituito.

lambda è una parola chiave python che funge da pseudo-funzione. Quindi, quando si passa l'oggetto player, restituirà player.totalScore. Così, iterable passò operato max ordinerà secondo l'keytotalScore degli oggetti player impartite & restituirà la player che ha la massima totalScore.

Se non viene fornito l'argomento key, il massimo viene restituito 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')