Python-Lambda-Funktionen: Syntax, tatsächliche Verwendung und wann man sie nicht verwendet
Ein Lambda ist eine kleine Funktion, die Sie in einer Zeile genau dort schreiben können, wo Sie sie benötigen. Lernen Sie die Syntax, die Stellen, an denen Lambdas wirklich helfen, die Falle, die erfahrene Entwickler fängt, und wann eine normale Funktion einfach besser ist.
- Ein Lambda ist eine anonyme Funktion, die auf einen einzigen Ausdruck beschränkt ist.
- Am besten eignet es sich als Kurzargument, insbesondere als
keyfürsorted,minundmax. - Ein Listenverständnis ist normalerweise klarer als
mapoderfiltermit einem Lambda. - Wenn Sie einem Namen ein Lambda zuweisen, schreiben Sie stattdessen eine
def.
Sie müssen Produkte nach Preis sortieren. Das Schreiben einer separaten benannten Funktion, nur um „den Preis verwenden“ zu sagen, fühlt sich wie eine Menge Zeremonie an. Python-Lambda-Funktionen ermöglichen es Ihnen, dieses kleine Stück Logik inline zu definieren, genau dort, wo Sie es verwenden.
Lambdas sind praktisch, können aber auch leicht überbeansprucht werden. Dieser Leitfaden zeigt, wo sie wirklich helfen und wo sie die Lesbarkeit des Codes erschweren. Wir haben jedes Beispiel auf Python 3.13 ausgeführt und die angezeigte Ausgabe stammt von diesem Lauf.
Was ist ein Lambda?
Ein Lambda ist eine Funktion ohne Namen, geschrieben mit dem Schlüsselwort lambda:
lambda arguments: expression
Es akzeptiert eine beliebige Anzahl von Argumenten und gibt automatisch den Wert eines einzelnen Ausdrucks zurück. Es gibt kein Schlüsselwort return und keinen Anweisungskörper.
square = lambda x: x * x
print(square(4)) # 16
print((lambda a, b=10: a + b)(5)) # 15
Die zweite Zeile definiert ein Lambda mit einem Standardargument und ruft es sofort auf. Sie würden dies selten in echtem Code schreiben, aber es zeigt, dass ein Lambda ein gewöhnliches Funktionsobjekt ist.
Lambda vs. Def
Diese beiden erzeugen Funktionen, die sich gleich verhalten:
square = lambda x: x * x
def square_def(x):
return x * x
print(square(4), square_def(4)) # 16 16
print(square.__name__, square_def.__name__) # <lambda> square_def
Schauen Sie sich die Namen an. Jedes Lambda heißt einfach <lambda>, daher können Fehlermeldungen und Protokolle Ihnen nicht sagen, welches fehlgeschlagen ist. Dies ist der Hauptgrund dafür, dass Styleguides wie PEP 8 eine def empfehlen, wenn Sie einer Funktion einen Namen geben möchten.
| Funktion | Lambda |
def |
|---|---|---|
| Name | Anonym | Benannt |
| Körper | Ein Ausdruck | Beliebig viele Aussagen |
| Rückkehr | Implizit | Explizit return |
| Docstring- und Typhinweise | Nicht unterstützt | Unterstützt |
| Lesbare Rückverfolgungen | Zeigt <lambda> |
Zeigt den Namen an |
| Am besten für | Kurze Wegwerfargumente | Alles andere |
Sortieren mit Schlüssel: die beste Verwendung
Funktionen wie sorted, min und max akzeptieren eine key-Funktion, die entscheidet, was verglichen werden soll. Hier glänzen Lambdas:
products = [("pen", 10), ("bag", 900), ("book", 250)]
sorted(products, key=lambda p: p[1])
# [('pen', 10), ('book', 250), ('bag', 900)]
max(products, key=lambda p: p[1])
# ('bag', 900)
Um nach mehreren Dingen zu sortieren, geben Sie ein Tupel zurück. Hier werden die Personen nach Alter sortiert, zuerst nach den Ältesten und dann nach Namen:
people = [{"name": "Asha", "age": 31}, {"name": "Ben", "age": 25},
{"name": "Dev", "age": 31}]
[p["name"] for p in sorted(people, key=lambda p: (-p["age"], p["name"]))]
# ['Asha', 'Dev', 'Ben']
Das Minuszeichen kehrt die Reihenfolge nur für die Nummer um. Manchmal braucht man überhaupt kein Lambda, weil eine vorhandene Funktion den Job bereits erledigt. Vergleichen Sie die Standardsortierung mit einer Sortierung ohne Berücksichtigung der Groß- und Kleinschreibung:
names = ["Asha", "ben", "Chitra", "dev"]
sorted(names) # ['Asha', 'Chitra', 'ben', 'dev']
sorted(names, key=str.lower) # ['Asha', 'ben', 'Chitra', 'dev']
Standardmäßig stehen alle großgeschriebenen Wörter an erster Stelle. Das Übergeben von str.lower behebt das Problem ohne Lambda. Das Modul operator bietet ähnliche Helfer, etwa itemgetter(1) für lambda p: p[1].
Karte und Filter
map wendet eine Funktion auf jedes Element an und filter behält die Elemente bei, für die es „true“ zurückgibt. Beide arbeiten mit Lambdas, vergleichen sie jedoch jeweils mit einem Listenverständnis:
nums = [1, 2, 3, 4, 5, 6]
list(map(lambda n: n * 10, nums)) # [10, 20, 30, 40, 50, 60]
[n * 10 for n in nums] # [10, 20, 30, 40, 50, 60]
list(filter(lambda n: n % 2 == 0, nums)) # [2, 4, 6]
[n for n in nums if n % 2 == 0] # [2, 4, 6]
Die Ergebnisse sind identisch und die meisten Python-Entwickler finden die Erläuterungen einfacher zu lesen. Beachten Sie auch, dass map und filter verzögerte Iteratoren zurückgeben, sodass Sie list() benötigen, um die Werte zu sehen. Unser Leitfaden zum Python-Listenverständnis behandelt diesen Stil ausführlich. map lässt sich immer noch gut mit einer vorhandenen benannten Funktion lesen, wie in map(str.strip, lines).
reduzieren
functools.reduce kombiniert Elemente zu einem einzigen Wert und liefert ein laufendes Ergebnis:
from functools import reduce
reduce(lambda acc, n: acc + n, nums, 0) # 21
sum(nums) # 21
Verwenden Sie für allgemeine Aufgaben wie Summen eine integrierte Funktion wie sum, max oder any. Behalten Sie reduce für seltenere Fälle bei und ziehen Sie eine einfache Schleife in Betracht, wenn das Lambda kompliziert aussieht.
Bedingungen in einem Lambda
Sie können in einem Lambda keine if-Anweisung verwenden, aber Sie können einen bedingten Ausdruck verwenden:
label = lambda total: "large" if total >= 1000 else "small"
label(1200), label(300)
# ('large', 'small')
Eine Bedingung ist in Ordnung. Sobald Sie mit der Verschachtelung beginnen, müssen die Leser hart arbeiten, was ein klares Zeichen dafür ist, zu einer def-Anweisung mit gewöhnlichen if-Anweisungen zu wechseln.
Lambdas, die Funktionen zurückgeben
Eine Funktion kann ein Lambda erstellen und zurückgeben, das sich einen Wert aus seiner Umgebung merkt:
def multiplier(n):
return lambda x: x * n
double = multiplier(2)
double(7) # 14
Dies funktioniert aufgrund von Abschlüssen, die unser Artikel über JavaScript-Abschlüsse in einer anderen Sprache erklärt. Pythons functools.partial bietet eine weitere Möglichkeit, Argumente vorab auszufüllen.
Die Late-Binding-Falle
Das erwischt irgendwann fast jeden. Wir haben drei Lambdas in einer Schleife erstellt und erwartet, dass jedes seine eigene Zahl zurückgibt:
funcs = [lambda: i for i in range(3)]
[f() for f in funcs]
# [2, 2, 2]
Alle drei geben 2 zurück. Ein Lambda erfasst nicht den Wert von i, wenn es erstellt wird. Es sucht nach der Variablen, wenn sie aufgerufen wird, und bis dahin ist die Schleife beendet, so dass i bei 2 bleibt. Die übliche Lösung besteht darin, den Wert als Standardargument zu erfassen, da Standardwerte zum Zeitpunkt der Definition ausgewertet werden:
funcs = [lambda i=i: i for i in range(3)]
[f() for f in funcs]
# [0, 1, 2]
Dies gilt nicht nur für Lambdas, da sich eine def innerhalb einer Schleife genauso verhält. Bei Lambdas tritt es einfach häufiger auf, weil sie so häufig in Schleifen erstellt werden, beispielsweise beim Anhängen von Schaltflächenrückrufen.
Tipp: Wenn Sie eine Funktion pro Element benötigen, überlegen Sie, ob Sie überhaupt viele Funktionen benötigen. Oft ist eine einzelne Funktion, die das Element als Argument verwendet, klarer und vermeidet die Falle vollständig.
Nachschlagetabellen für kleine Funktionen
Lambdas passen perfekt in ein Wörterbuch, das Namen kleinen Operationen zuordnet:
ops = {
"add": lambda a, b: a + b,
"sub": lambda a, b: a - b,
}
ops["sub"](10, 3) # 7
Dies kann eine lange Kette von if und elif ersetzen. Das Python-Wörterbuch-Handbuch deckt weitere Wörterbuchmuster ab, und das Modul operator bietet bereits operator.add und operator.sub.
Grenzen von Lambdas
- Nur ein Ausdruck. Keine Zuweisungen mit
=, keine Schleifen und keinetryBlöcke. - Keine Aussagen. Das Schreiben von
lambda x: return xschlägt mit einerSyntaxErrorfehl, wie unser Test bestätigte. - Keine Dokumentzeichenfolge oder Typhinweise. Tools und Reader erhalten weniger Hilfe.
- Schwierigeres Debuggen. Fehler deuten auf
<lambda>statt auf einen hilfreichen Namen.
Lambdas können natürlich immer noch Ausnahmen auslösen. Die Handhabung dieser funktioniert genauso wie bei jeder anderen Funktion, wie unter Python-Ausnahmebehandlung beschrieben.
Wann man kein Lambda verwenden sollte
| Situation | Bessere Wahl |
|---|---|
| Es einem Namen zuweisen | def |
| Logik benötigt mehr als eine Zeile | def |
| Eine Liste transformieren oder filtern | Ein Listenverständnis |
| Summieren oder Finden eines Maximums | sum, max, min |
| Ein Element oder Attribut abrufen | operator.itemgetter oder attrgetter |
| Das gleiche Lambda erscheint an mehreren Stellen | Eine benannte Funktion, die Sie testen können |
Der letzte Punkt ist wichtig. Es lohnt sich, eine wiederzuverwendende Logik zu testen, und eine benannte Funktion ist weitaus einfacher zu testen, wie unser Pytest-Tutorial zeigt.
Fazit
Ein gutes Lambda ist kurz genug, um auf einen Blick gelesen zu werden, und wird einmal verwendet, normalerweise als Argument. Sortierschlüssel sind das klassische Beispiel. Um Ihren eigenen Code zu überprüfen, suchen Sie nach = lambda und wandeln Sie diese in benannte Funktionen um. Schauen Sie sich dann map oder filter mit einem Lambda an und prüfen Sie, ob sich ein Verständnis besser liest.
Häufige Fragen
Was ist eine Lambda-Funktion in Python?
Es handelt sich um eine kleine anonyme Funktion, die mit dem Schlüsselwort Lambda erstellt wird. Es akzeptiert Argumente und gibt den Wert eines einzelnen Ausdrucks ohne Namen oder Rückgabeanweisung zurück.
Kann ein Python-Lambda mehrere Zeilen haben?
Nein. Ein Lambda ist auf einen Ausdruck beschränkt. Sie können es über Zeilen innerhalb von Klammern aufteilen, aber es kann trotzdem keine Anweisungen enthalten. Verwenden Sie daher def für komplexere Logik.
Kann ich if else in einem Lambda verwenden?
Sie können einen bedingten Ausdruck verwenden, z. B. Lambda x: „groß“, wenn x > 10, sonst „klein“. Eine if-Anweisung mit einem Block ist nicht zulässig.
Sind Lambdas schneller als normale Funktionen?
Nicht sinnvoll. Beide erzeugen die gleiche Art von Funktionsobjekt. Wählen Sie zwischen ihnen aus Gründen der Lesbarkeit und nicht der Leistung.
Sollte ich eine Karte mit Lambda oder ein Listenverständnis verwenden?
Die meisten Python-Entwickler bevorzugen aus Gründen der Lesbarkeit ein Listenverständnis. „map“ ist sinnvoll, wenn Sie bereits über eine benannte Funktion verfügen, z. B. „map(str.strip,lines“).
Lerne weiter
Benötigen Sie Hilfe beim Testen, WordPress oder SEO?
Wir helfen Teams, bessere Software zu liefern und ihre Websites zu erweitern. Sagen Sie uns, woran Sie gerade arbeiten, und wir schlagen Ihnen einen klaren nächsten Schritt vor.
Weitere Anleitungen finden Sie unter Tests, KI und moderne Entwicklung
Hat Ihnen dieser Artikel gefallen? Wählen Sie ein Thema und springen Sie direkt in unsere neuesten Tutorials.
KI-Halluzinationen erklärt: Warum Sprachmodelle Dinge erfinden und wie man sie reduziert
KI-Halluzinationen erklärt: Was sie sind, warum Sprachmodelle sie produzieren, gängige Typen, wie man sie mit Erdung und Eingabeaufforderungen reduz…
Artikel lesen →DevOpsErklärte Umgebungsvariablen: .env-Dateien, Geheimnisse und Konfiguration richtig gemacht
Umgebungsvariablen anhand von Python-Beispielen erklärt, die wir ausgeführt haben: Sie lesen und festlegen, warum jeder Wert ein String ist, .env-Da…
Artikel lesen →SoftwareentwicklungAPI-Ratenbegrenzung erklärt: Algorithmen, Header und Behandlung von 429-Fehlern
API-Ratenbegrenzung anhand einer von uns durchgeführten Simulation erklärt: Token-Bucket, festes Fenster, gleitendes Fenster, 429 Antworten, Ratenbe…
Artikel lesen →TestautomatisierungSpott in Python: unittest.mock, Patch und die Fehler, die Tests zum Lügen machen
Mocking in Python mit unittest.mock, getestet: Mock und return_value, side_effect, Patchen, wo ein Name verwendet wird, Spezifikation und Autospec, …
Artikel lesen →SoftwaretestsCode-Abdeckung erklärt: Leitungs- und Zweigstellenabdeckung und was 100 % wirklich bedeutet
Erklärung der Codeabdeckung anhand eines echten Coverage.py-Laufs: Zeilen-, Zweig- und Bedingungsabdeckung, Lesen eines Berichts, warum bei 100 % Ab…
Artikel lesen →Datenbanken & SQLDELETE vs. TRUNCATE vs. DROP in SQL: Unterschiede, Rollback und Verwendungszweck
DELETE vs. TRUNCATE vs. DROP erklärt mit getestetem SQL: was jeweils entfernt wird, Rollback, Trigger, Identitätsrücksetzung, Geschwindigkeit und wi…
Artikel lesen →Datenbanken & SQLErklärte SQL-Ansichten: Erstellen, nutzen und vermeiden Sie Fallstricke mit Beispielen
SQL-Ansichten anhand der von uns ausgeführten Abfragen erklärt: Erstellen einer Ansicht, Live-Ergebnisse, Ausblenden von Spalten, Leistung, aktualis…
Artikel lesen →SoftwareentwicklungTypeScript-Schnittstelle vs. Typ: Echte Unterschiede, getestet mit dem Compiler
TypeScript-Schnittstelle vs. Typ, überprüft mit dem echten Compiler: Was beide können, was nur einer kann, Deklarationszusammenführung, Erweiterunge…
Artikel lesen →SoftwareentwicklungPython *args und **kwargs erklärt: Flexible Funktionen mit klaren Beispielen
Python *args und **kwargs erklärt mit Code, den wir ausgeführt haben: Packen und Entpacken, Parameterreihenfolge, Nur-Schlüsselwort- und Nur-Positio…
Artikel lesen →SoftwareentwicklungPython-Lambda-Funktionen: Syntax, tatsächliche Verwendung und wann man sie nicht verwendet
Python-Lambda-Funktionen erklärt mit Code, den wir ausgeführt haben: Syntax, Sortierung mit Schlüssel, Karte und Filter, Abschlüsse, die Late-Bindin…
Artikel lesen →Künstliche IntelligenzWas sind KI-Agenten? Wie sie funktionieren, mit einer einfachen Agentenschleife, die Sie ausführen können
Was sind KI-Agenten? Eine einfache Anleitung zur Agentenschleife, zu Tools, Speicher und Leitplanken, mit einer kleinen Python-Schleife, die wir aus…
Artikel lesen →DevOpsÜberwachung vs. Beobachtbarkeit: Der wahre Unterschied, mit Protokollen, Metriken und Traces
Überwachung vs. Beobachtbarkeit erklärt: bekannte und unbekannte Fehler, Protokolle, Metriken und Spuren, eine exemplarische Vorgehensweise für Chec…
Artikel lesen →DevOpsDocker-Volumes vs. Bind Mounts: Containerdaten auf die richtige Art und Weise beibehalten
Docker-Volumes vs. Bind-Mounts erklärt: Warum Containerdaten verschwinden, benannte Volumes, Bind-Mounts, tmpfs, Compose-Beispiele, Backups, Berecht…
Artikel lesen →TestautomatisierungTDD vs. BDD: Hauptunterschiede, eine Funktion, die auf beide Arten entwickelt wurde und wann sie jeweils verwendet werden sollte
TDD vs. BDD erklärt mit einer Rabattfunktion, die in beide Richtungen aufgebaut ist: Rot-Grün-Refaktor mit Code, den wir ausgeführt haben, Gegeben-W…
Artikel lesen →SoftwareentwicklungGit merge vs rebase: Unterschiede, Beispiele und wann man was nutzt
Git merge vs rebase erklärt mit echter Log-Ausgabe, einer Vergleichstabelle, der goldenen Regel des Rebase und einem sicheren Team-Workflow.
Artikel lesen →SoftwareentwicklungPython List Comprehension: Syntax, Beispiele und wann man darauf verzichtet
Python List Comprehension erklärt: Syntax, Filter, if-else, verschachtelte Schleifen, gemessene Zeiten und Fälle, in denen eine normale for-Schleife…
Artikel lesen →Datenbanken & SQLSQL Joins erklärt mit Beispielen (Inner, Left, Right, Full)
SQL Joins Schritt für Schritt mit Beispieltabellen und Abfragen verstehen: INNER, LEFT, RIGHT, FULL, CROSS und SELF, plus typische Fehler und Perfor…
Artikel lesen →