Pythons Lambda mit Unterstrich für ein Argument?

84

Was macht der folgende Code?

a = lambda _:True

Nach dem, was ich in der interaktiven Eingabeaufforderung gelesen und getestet habe, scheint es eine Funktion zu sein, die immer zurückkehrt True.

Verstehe ich das richtig? Ich hoffe zu verstehen, warum auch ein Unterstrich ( _) verwendet wurde.

Laienkatze
quelle
10
Für diejenigen, die was für ein parameterloses Lambda, ist die Syntaxlambda : True
Robino
17
Etwas , das ich diesen Beitrag nicht mag , ist , dass die Frage Titel Gespräche über eine Lambda - Funktion „mit NO Variablen“ , aber die Frage Körper, und fast alle Antworten, geben Beispiele für eine Lambda - Funktionen mit einer Variablen / Argument. Diese Variable hat zufällig einen seltsamen Namen _anstelle von xoder aoder was auch immer. Wenn jemand wissen möchte, wie man eine Lambda-Funktion schreibt, die keine Argumente akzeptiert; So geht's: Definieren Sie es so : my_lambda = lambda : 255. Nennen Sie es so: x = my_lambda()Sie können durch einen 255beliebigen Rückgabewert ersetzen .
Zahnstocher Anemone
2
@ToothpickAnemone tolle Antwort! Ich benutze heutzutage meistens Lambda ohne Variablen zum Initialisieren von Standarddicts. Ich hoffe, es ist nützlich für Leute, die diesen Thread lesen. ht = {} ht = defaultdict (Lambda: 0, ht)
Laycat

Antworten:

143

Das _ist der Variablenname. Versuch es. (Dieser Variablenname ist normalerweise ein Name für eine ignorierte Variable. Sozusagen ein Platzhalter.)

Python:

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

>>> l("foo")
True

Dieses Lambda erfordert also ein Argument . Wenn Sie ein Lambda ohne Argument wünschen , das immer zurückgibt True, gehen Sie folgendermaßen vor:

>>> m = lambda: True
>>> m()
True
winklerrr
quelle
7
@dopatraman hat es mit Python 3.6.2under getestet Mac OS 10.12und es funktioniert.
Winklerrr
6
Vielleicht können Sie die Information hinzufügen, dass der Variablenname _häufig verwendet wird, wenn die Variable selbst nicht wirklich benötigt wird. Es ist wie eine "Wegwerfvariable", nur ein Platzhalter, der keinen Nutzen hat.
Winklerrr
1
@dopatraman In Ipython enthält _ den vom letzten Ausdruck zurückgegebenen Wert. Ich vermeide es aus diesem Grund, _ zu verwenden. stackoverflow.com/questions/17580289/…
Taro Kiritani
7

Unterstrich ist eine Python-Konvention zum Benennen einer nicht verwendeten Variablen (z. B. statische Analysewerkzeuge melden sie nicht als nicht verwendete Variable). In Ihrem Fall wird das Lambda-Argument nicht verwendet, aber das erstellte Objekt ist eine Einzelargumentfunktion, die immer zurückgibt True. Ihr Lambda ist also etwas analog zur Konstantenfunktion in der Mathematik.

Łukasz Rogalski
quelle
Es ist nicht nur eine Python-Konvertierung, sondern auch eine sprachunabhängige Konvertierung. Der Unterstrich zeigt an, dass eine Variable vorübergehend oder unbedeutend ist
Sławomir Lenart,
6

Es scheint eine Funktion zu sein, die unabhängig davon True zurückgibt.

Ja, es ist eine Funktion (oder Lambda), die True zurückgibt. Der Unterstrich , der normalerweise ein Platzhalter für eine ignorierte Variable ist, ist in diesem Fall nicht erforderlich.

Ein Beispiel für einen Anwendungsfall für eine solche Funktion (die fast nichts bewirkt):

dd = collections.defaultdict(lambda: True)

Bei Verwendung als Argument für ein Standarddikt können Sie Trueeinen allgemeinen Standardwert verwenden.

miku
quelle
4

Lambda bedeutet eine Funktion. Die obige Aussage ist dasselbe wie das Schreiben

def f(_):
    return True

Für Lambda muss eine Variable vorhanden sein. Also übergeben Sie ihm eine Variable namens _(Ähnlich könnten Sie übergeben x, y..)

Hyaden
quelle
3

Der Unterstrich _ist ein gültiger Bezeichner und wird hier als Variablenname verwendet. Es wird immer Truefür das an die Funktion übergebene Argument zurückgegeben.

>>>a('123') 
True
Haccks
quelle
Hallo, danke für die schnelle Antwort. Also ist es eine anonyme Funktion, die immer true zurückgibt?
Laycat
@laycat; Ja. Es wird immer true zurückgeben.
Haccks
2

Unten ist die fragliche Codezeile:

a = lambda _:True

Es wird eine Funktion mit einem Eingabeparameter erstellt : _. Unterstrich ist eine ziemlich seltsame Wahl des Variablennamens, aber es ist nur ein Variablenname. Sie können _überall verwenden, auch wenn Sie keine Lambda-Funktionen verwenden. Zum Beispiel anstelle von ....

my_var = 5
print(my_var)

Sie könnten schreiben:

_ = 5
print(_)

Es gab jedoch einen Grund, _der als Name des Parameternamens anstelle von so etwas wie xoder verwendet wurde input. Wir werden gleich darauf zurückkommen.

Zunächst müssen wir wissen, dass das Lambda-Schlüsselwort eine Funktion erstellt, die der defSyntax ähnelt , jedoch eine andere hat. Die Definition der Lambda-Funktion a = lambda _:Trueähnelt dem Schreiben:

def a(_):
    return True

Es erstellt eine Funktion amit einem Eingabeparameter _und gibt diese zurück True. Man hätte genauso leicht schreiben können a = lambda x:True, mit einem xanstelle eines Unterstrichs. Die Konvention besteht jedoch darin, _als Variablenname zu verwenden, wenn wir diese Variable nicht verwenden möchten. Folgendes berücksichtigen:

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

Beachten Sie, dass der Schleifenindex niemals innerhalb des Schleifenkörpers verwendet wird. Wir möchten einfach, dass die Schleife eine bestimmte Anzahl von Malen ausgeführt wird. Wie winklerrrgeschrieben, "ist der Variablenname _[...] wie eine" Wegwerfvariable ", nur ein Platzhalter, der keinen Nutzen hat."

Ebenso mit `` a = lambda x: Stimmt der Eingangsparameter nicht innerhalb des Körpers der Funktion verwendet wird. Es spielt keine Rolle, was das Eingabeargument ist, solange es eines gibt. Der Autor dieser Lambda-Funktion schrieb _anstelle von so etwas x, um anzuzeigen, dass die Variable nicht verwendet werden würde.

Beachten Sie, dass das Lambda ist ein Argument hat; Also schreiben

a()wird einen Fehler auslösen.

Wenn Sie ein Lambda ohne Argument wollen, schreiben Sie so etwas:

 bar = lambda: True

Jetzt bar()funktioniert das Anrufen ohne Argumente einwandfrei. Ein Lambda, das keine Argumente akzeptiert, muss nicht immer denselben Wert zurückgeben:

import random
process_fruit = lambda : random.random()

Die obige Lambda-Funktion ist komplexer als nur etwas, das immer dieselbe Konstante zurückgibt.

Ein Grund, warum Programmierer uns manchmal das lambdaSchlüsselwort anstelle geben, def sind Funktionen, die besonders kurz und einfach sind. Beachten Sie, dass eine lambdaDefinition normalerweise alle in eine Zeile passen kann, während es schwierig ist, dasselbe mit einer def-Anweisung zu tun. Ein weiterer Grund für die Verwendung lambdaanstelle von defsf, wenn die Funktion nicht erneut verwendet wird. Wenn wir die Funktion später nicht erneut aufrufen möchten, müssen Sie der Funktion keinen Namen geben. Betrachten Sie beispielsweise den folgenden Code:

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

Jetzt machen wir folgenden Anruf:

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

Beachten Sie, dass lambda x: x**2kein Etikett angegeben ist. Dies liegt daran, dass wir es wahrscheinlich später nicht mehr anrufen werden. Es war nur etwas Kurzes und Einfaches, das wir vorübergehend brauchten.

Die Tatsache, dass Lambda-Funktionen keinen Namen erhalten müssen, ist die Quelle eines anderen Namens, um sie zu beschreiben: "anonyme Funktionen".

Beachten Sie auch, dass Lambda-Anweisungen insofern wie ein Funktionsaufruf sind, als sie einen Verweis auf die von ihnen erstellte Funktion zurückgeben. Folgendes ist illegal:

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

Während apply_to_each(lambda x: x**2 range(0, 101))ist in Ordnung.

Wir verwenden also lambdaanstelle defund _anstelle eines langen Variablennamens, wenn wir etwas Kurzes, Süßes möchten und es wahrscheinlich später nicht mehr verwenden möchten.

IdleCustard
quelle