Lambda di Python con trattino basso per un argomento?


85

Cosa fa il codice seguente?

a = lambda _:True

Da quello che ho letto e testato nel prompt interattivo, sembra essere una funzione che ritorna sempre True.

Lo capisco correttamente? Spero di capire perché è _stato utilizzato anche un trattino basso ( ).


10
Per quelli che cos'è un lambda senza parametri, la sintassi èlambda : True
Robino

18
Qualcosa che mi piace di questo intervento è che il titolo questione parla di una funzione lambda "con NO variabili", ma il corpo domanda, e quasi tutte le risposte, danno esempi di funzioni lambda con una variabile / argomento. Quella variabile sembra avere un nome strano _, invece di xo ao altro. Se qualcuno vuole sapere come scrivere una funzione lambda che non accetta argomenti; ecco come: Definire in questo modo: my_lambda = lambda : 255. Chiamalo in questo modo: x = my_lambda()puoi sostituire 255con qualsiasi valore di ritorno che ti piace.
Stuzzicadenti Anemone

2
@ToothpickAnemone ottima risposta! Io uso principalmente lambda senza variabili per inizializzare i defaultdict in questi giorni. spero che sia utile alle persone che leggono questo thread. ht = {} ht = defaultdict (lambda: 0, ht)
laycat

Risposte:


147

Il _nome della variabile è. Provalo. (Questo nome di variabile è solitamente un nome per una variabile ignorata. Un segnaposto per così dire.)

Pitone:

>>> l = lambda _: True
>>> l()
<lambda>() missing 1 required positional argument: '_'

>>> l("foo")
True

Quindi questo lambda richiede un argomento . Se vuoi un lambda senza argomenti che ritorni sempre True, fai questo:

>>> m = lambda: True
>>> m()
True

7
@dopatraman l'ha testato con Python 3.6.2under Mac OS 10.12e funziona.
winklerrr

6
Forse potresti aggiungere le informazioni che il nome della variabile _è comunemente usato quando la variabile stessa non è realmente necessaria. È come una "variabile usa e getta", solo un segnaposto che non serve.
winklerrr

1
@dopatraman In Ipython, _ contiene il valore restituito dall'ultima espressione. Evito di usare _ per questo motivo. stackoverflow.com/questions/17580289/…
Taro Kiritani

7

Il carattere di sottolineatura è una convenzione Python per nominare una variabile inutilizzata (ad esempio, gli strumenti di analisi statica non la segnalano come variabile inutilizzata). Nel tuo caso l'argomento lambda non è utilizzato, ma l'oggetto creato è una funzione con un singolo argomento che restituisce sempre True. Quindi il tuo lambda è in qualche modo analogo alla funzione costante in matematica.


non solo la conversione in Python, è indipendente dalla lingua e il carattere di sottolineatura viene utilizzato per indicare che una variabile è temporanea o insignificante
Sławomir Lenart

6

sembra essere una funzione che restituisce True a prescindere.

Sì, è una funzione (o lambda) che restituisce True. Il carattere di sottolineatura , che di solito è un segnaposto per una variabile ignorata, non è necessario in questo caso.

Un caso d'uso di esempio per una tale funzione (che non fa quasi nulla):

dd = collections.defaultdict(lambda: True)

Quando viene utilizzato come argomento di un defaultdict , puoi avere Truecome valore predefinito generale.


4

Lambda significa una funzione. La dichiarazione di cui sopra è uguale alla scrittura

def f(_):
    return True

Per lambda deve essere presente una variabile. Quindi gli passi una variabile chiamata _(Allo stesso modo potresti passare x, y..)


3

Il carattere di sottolineatura _è un identificatore valido e viene utilizzato qui come nome di variabile. Restituirà sempre Truel'argomento passato alla funzione.

>>>a('123') 
True

Ciao, grazie per la rapida risposta. quindi è una funzione anonima che restituisce sempre true?
laycat

@laycat; Sì. Tornerà sempre vero.
haccks

2

Di seguito è riportata la riga di codice in questione:

a = lambda _:True

Si crea una funzione con un parametro di input: _. Il carattere di sottolineatura è una scelta piuttosto strana del nome di variabile, ma è solo un nome di variabile. Puoi usarlo _ovunque, anche quando non usi le funzioni lambda. Ad esempio, invece di ....

my_var = 5
print(my_var)

Potresti scrivere:

_ = 5
print(_)

Tuttavia, c'era un motivo che è _stato utilizzato come nome del nome del parametro invece di qualcosa come xo input. Ci arriveremo tra un momento.

Innanzitutto, dobbiamo sapere che la parola chiave lambda costruisce una funzione, simile a def, ma con una sintassi diversa. La definizione della funzione lambda,, a = lambda _:Trueè simile alla scrittura:

def a(_):
    return True

Crea una funzione denominata acon un parametro di input _e restituisce True. Si potrebbe scrivere altrettanto facilmente a = lambda x:True, con un carattere xdi sottolineatura invece di. Tuttavia, la convenzione è quella di utilizzare _come nome di variabile quando non si intende utilizzare quella variabile. Considera quanto segue:

for _ in range(1, 11):
    print('pear')

Si noti che l'indice del ciclo non viene mai utilizzato all'interno del corpo del ciclo. Vogliamo semplicemente che il ciclo venga eseguito un numero di volte specificato. Come winklerrrha scritto, "il nome della variabile _è [...] come una" variabile usa e getta ", solo un segnaposto che non serve."

Allo stesso modo, con `` a = lambda x: True il parametro di input non viene utilizzato all'interno del corpo della funzione. Non importa quale sia l'argomento di input, purché ce ne sia uno. L'autore di quella funzione lambda ha scritto _invece di qualcosa di simile x, per indicare che la variabile non sarebbe stata utilizzata.

Si noti che il lambda non ha un argomento; Quindi, scrivere

a(), genererà un errore.

Se vuoi un lambda senza argomenti scrivi qualcosa del genere:

 bar = lambda: True

Ora la chiamata bar(), senza argomenti, funzionerà perfettamente. Un lambda che non accetta argomenti non deve sempre restituire lo stesso valore:

import random
process_fruit = lambda : random.random()

La funzione lambda sopra è più complessa di un qualcosa che restituisce sempre la stessa costante.

Uno dei motivi per cui i programmatori a volte usano la lambdaparola chiave invece di def è per le funzioni che sono particolarmente brevi e semplici. Notare che una lambdadefinizione di solito può stare tutta su una riga, mentre è difficile fare lo stesso con un'istruzione def. Un altro motivo per utilizzare al lambdaposto di defsf quando la funzione non verrà utilizzata di nuovo. Se non vogliamo richiamare la funzione in un secondo momento, non è necessario assegnare un nome alla funzione. Si consideri ad esempio il codice seguente:

def apply_to_each (transform, in_container): out_container = list () for idx, item in enumerate (container, 0): out_container [idx] = transform (item) return out_container

Ora facciamo la seguente chiamata:

squares  = apply_to_each(lambda x: x**2 range(0, 101))

Si noti che lambda x: x**2non viene assegnata un'etichetta. Questo perché probabilmente non lo richiameremo più tardi, era solo qualcosa di breve e semplice di cui avevamo bisogno temporaneamente.

Il fatto che non sia necessario dare un nome alle funzioni lambda è la fonte di un altro nome per descriverle: "funzioni anonime".

Si noti inoltre che le istruzioni lambda sono come una chiamata di funzione in quanto restituiscono un riferimento alla funzione che creano. Quanto segue è illegale:

apply_to_each(def foo(x): x**2 ,  range(0, 101))

Considerando che apply_to_each(lambda x: x**2 range(0, 101))va bene.

Quindi, usiamo al lambdaposto di defe _invece di un nome lungo di variabile quando vogliamo qualcosa di breve, dolce e probabilmente non lo vogliamo usare di nuovo in seguito.

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.