¿Lambda de Python con guión bajo para un argumento?

84

¿Qué hace el siguiente código?

a = lambda _:True

Por lo que leí y probé en el indicador interactivo, parece ser una función que siempre regresa True.

¿Estoy entendiendo esto correctamente? Espero entender por qué también _se usó un guión bajo ( ).

laico
fuente
10
Para aquellos que qué lambda sin parámetros, la sintaxis eslambda : True
Robino
17
Algo que no me gusta de esta publicación es que el título de la pregunta habla de una función lambda " sin variables", pero el cuerpo de la pregunta, y casi todas las respuestas, dan ejemplos de funciones lambda que tienen una variable / argumento. Esa variable sólo pasa a tener un nombre extraño _, en lugar de xo ao lo que sea. Si alguien quiere saber cómo escribir una función lambda que no tenga argumentos; he aquí cómo: Definir esta manera: my_lambda = lambda : 255. Llámelo así: x = my_lambda()puede reemplazarlo 255con el valor de retorno que desee.
Palillo de dientes Anemone
2
@ ToothpickAnemone ¡gran respuesta! Principalmente uso lambda sin variables para inicializar los dictos predeterminados en estos días. Espero que sea útil para las personas que lean este hilo. ht = {} ht = defaultdict (lambda: 0, ht)
laycat

Respuestas:

143

El _nombre de la variable is. Intentalo. (Este nombre de variable suele ser el nombre de una variable ignorada. Un marcador de posición, por así decirlo).

Pitón:

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

>>> l("foo")
True

Entonces, esta lambda requiere un argumento . Si desea una lambda sin argumento que siempre regrese True, haga esto:

>>> m = lambda: True
>>> m()
True
winklerrr
fuente
7
@dopatraman lo probó con Python 3.6.2under Mac OS 10.12y funciona.
winklerrr
6
Tal vez podría agregar la información de que el nombre de la variable _se usa comúnmente cuando la variable en sí no es realmente necesaria. Es como una "variable desechable", solo un marcador de posición que no sirve de nada.
winklerrr
1
@dopatraman En Ipython, _ contiene el valor devuelto por la última expresión. Evito usar _ por este motivo. stackoverflow.com/questions/17580289/…
Taro Kiritani
7

Subrayado es una convención de Python para nombrar una variable no utilizada (por ejemplo, las herramientas de análisis estático no la reportan como variable no utilizada). En su caso, el argumento lambda no se usa, pero el objeto creado es una función de un solo argumento que siempre regresa True. Entonces, su lambda es algo análoga a la función constante en matemáticas.

Łukasz Rogalski
fuente
no solo la conversión de Python, es un idioma independiente y el subrayado se usa para indicar que una variable es temporal o insignificante
Sławomir Lenart
6

parece ser una función que devuelve True independientemente.

Sí, es una función (o lambda) que devuelve True. El subrayado , que suele ser un marcador de posición para una variable ignorada, no es necesario en este caso.

Un caso de uso de ejemplo para una función de este tipo (que no hace casi nada):

dd = collections.defaultdict(lambda: True)

Cuando se usa como argumento para un defaultdict , puede tener Truecomo valor predeterminado general.

miku
fuente
4

Lambda significa función. La declaración anterior es lo mismo que escribir

def f(_):
    return True

Para lambda, una variable debe estar presente. Entonces le pasa una variable llamada _(De manera similar, podría pasar x, y..)

hyades
fuente
3

El subrayado _es un identificador válido y se utiliza aquí como nombre de variable. Siempre regresará Truepara el argumento pasado a la función.

>>>a('123') 
True
haccks
fuente
Hola, gracias por la rápida respuesta. ¿Entonces es una función anónima que siempre devuelve verdadero?
laycat
@laycat; Si. Siempre volverá verdadero.
haccks
2

A continuación se muestra la línea de código en cuestión:

a = lambda _:True

Se crea una función que tiene un parámetro de entrada: _. El subrayado es una elección bastante extraña de nombre de variable, pero es solo un nombre de variable. Puede usarlo en _cualquier lugar, incluso cuando no use funciones lambda. Por ejemplo, en lugar de ....

my_var = 5
print(my_var)

Podrías escribir:

_ = 5
print(_)

Sin embargo, hubo una razón por la que _se usó como el nombre del nombre del parámetro en lugar de algo como xo input. Llegaremos a eso en un momento.

Primero, necesitamos saber que la palabra clave lambda construye una función, similar a def, pero con diferente sintaxis. La definición de la función lambda`` a = lambda _:Truees similar a escribir:

def a(_):
    return True

Crea una función nombrada acon un parámetro de entrada _y regresa True. Se podría haber escrito a = lambda x:Truecon la misma facilidad , con xun guión bajo en lugar de un subrayado. Sin embargo, la convención es usar _como nombre de variable cuando no pretendemos usar esa variable. Considera lo siguiente:

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

Observe que el índice de bucle nunca se usa dentro del cuerpo del bucle. Simplemente queremos que el ciclo se ejecute un número específico de veces. Como se winklerrrha escrito, "el nombre de la variable_ es como [...] una" variable desechable ", sólo un marcador de posición que no sirve".

Del mismo modo, con `` a = lambda x: True, el parámetro de entrada no se usa dentro del cuerpo de la función. Realmente no importa cuál sea el argumento de entrada, siempre que haya uno. El autor de esa función lambda escribió en _lugar de algo como x, para indicar que la variable no se usaría.

Tenga en cuenta que el lambda no tiene un argumento; Entonces, escribiendo

a(), generará un error.

Si desea una lambda sin argumento, escriba algo como esto:

 bar = lambda: True

Ahora llamar bar(), sin argumentos, funcionará bien. Una lambda que no toma argumentos no siempre debe devolver el mismo valor:

import random
process_fruit = lambda : random.random()

La función lambda anterior es más compleja que algo que siempre devuelve la misma constante.

Una de las razones por las que los programadores a veces usan la lambdapalabra clave en lugar de def es para funciones que son especialmente breves y simples. Tenga en cuenta que una lambdadefinición generalmente puede caber todo en una línea, mientras que es difícil hacer lo mismo con una declaración def. Otra razón para usar en lambdalugar dedef sf cuando la función no se volverá a usar. Si no queremos volver a llamar a la función más tarde, entonces no es necesario darle un nombre a la función. Por ejemplo, considere el siguiente código:

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

Ahora hacemos la siguiente llamada:

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

Darse cuenta de lambda x: x**2 no se le da una etiqueta. Esto se debe a que probablemente no lo volveremos a llamar más tarde, era solo algo breve y simple que necesitábamos temporalmente.

El hecho de que a las funciones lambda no se les dé un nombre es la fuente de otro nombre para describirlas: "funciones anónimas".

También tenga en cuenta que las sentencias lambda son como una llamada de función en el sentido de que devuelven una referencia a la función que crean. Lo siguiente es ilegal:

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

Considerando que, apply_to_each(lambda x: x**2 range(0, 101))está bien.

Entonces, usamos en lambdalugar de defy en _lugar de un nombre de variable largo cuando queremos algo corto, dulce y probablemente no queremos usarlo de nuevo más tarde.

Crema de reposo
fuente