Python Lambda-functies: Syntaxis, echt gebruik en wanneer u ze niet moet gebruiken
Een lambda is een kleine functie die u in één regel kunt schrijven, precies daar waar u hem nodig heeft. Leer de syntaxis, de plaatsen waar lambda’s echt helpen, de valkuil waar ervaren ontwikkelaars in trappen en wanneer een normale functie gewoon beter is.
- Een lambda is een anonieme functie die beperkt is tot één enkele expressie.
- Het beste gebruik ervan is als kort argument, vooral de
keyvoorsorted,minenmax. - Een lijstbegrip is meestal duidelijker dan
mapoffiltermet een lambda. - Als u een lambda aan een naam toekent, schrijft u in plaats daarvan een
def.
U moet producten sorteren op prijs. Het schrijven van een aparte benoemde functie om alleen maar te zeggen “gebruik de prijs” voelt als veel ceremonieel. Met Python lambda-functies kun je dat kleine stukje logica inline definiëren, precies waar je het gebruikt.
Lambda’s zijn handig, maar ze kunnen ook gemakkelijk te veel worden gebruikt. Deze gids laat zien waar ze echt helpen en waar ze de code moeilijker leesbaar maken. We hebben elk voorbeeld uitgevoerd op Python 3.13, en de getoonde uitvoer is afkomstig van die run.
Wat is een lambda?
Een lambda is een functie zonder naam, geschreven met het trefwoord lambda:
lambda arguments: expression
Er zijn een willekeurig aantal argumenten nodig en retourneert automatisch de waarde van een enkele expressie. Er is geen return trefwoord en geen reeks uitspraken.
square = lambda x: x * x
print(square(4)) # 16
print((lambda a, b=10: a + b)(5)) # 15
De tweede regel definieert een lambda met een standaardargument en roept deze onmiddellijk aan. Je zou dit zelden in echte code schrijven, maar het laat zien dat een lambda een gewoon functieobject is.
lambda versus def
Deze twee produceren functies die zich hetzelfde gedragen:
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
Kijk naar de namen. Elke lambda heet gewoon <lambda>, dus foutmeldingen en logs kunnen u niet vertellen welke defect is. Dit is de belangrijkste reden waarom stijlgidsen zoals PEP 8 een def aanbevelen wanneer u een functie een naam wilt geven.
| Functie | lambda |
zeker |
|---|---|---|
| Naam | Anoniem | Genoemd |
| Lichaam | Eén uitdrukking | Een willekeurig aantal uitspraken |
| Keer terug | Impliciet | Expliciet return |
| Docstring- en typehints | Niet ondersteund | Ondersteund |
| Leesbare tracebacks | Toont <lambda> |
Toont de naam |
| Beste voor | Korte wegwerpargumenten | Al het andere |
Sorteren met sleutel: het beste gebruik
Functies zoals sorted, min en max accepteren een key-functie die beslist wat er moet worden vergeleken. Dit is waar lambda’s schitteren:
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)
Als u op verschillende dingen wilt sorteren, retourneert u een tupel. Hier worden mensen gesorteerd op leeftijd, eerst de oudste en vervolgens op naam:
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']
Het minteken keert de volgorde alleen voor het getal om. Soms heb je helemaal geen lambda nodig, omdat een bestaande functie het werk al doet. Vergelijk de standaardsortering met een hoofdletterongevoelige sortering:
names = ["Asha", "ben", "Chitra", "dev"]
sorted(names) # ['Asha', 'Chitra', 'ben', 'dev']
sorted(names, key=str.lower) # ['Asha', 'ben', 'Chitra', 'dev']
Standaard worden alle woorden met hoofdletters eerst geplaatst. Als u str.lower doorgeeft, wordt dit probleem opgelost zonder enige lambda. De module operator biedt vergelijkbare hulpmiddelen, zoals itemgetter(1) voor lambda p: p[1].
in kaart brengen en filteren
map past een functie toe op elk item, en filter behoudt de items waarvoor deze waar retourneert. Beide werken met lambda’s, maar vergelijk ze allemaal met een lijstbegrip:
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]
De resultaten zijn identiek en de meeste Python-ontwikkelaars vinden de begrippen gemakkelijker te lezen. Merk ook op dat map en filter luie iteratoren retourneren, dus je hebt list() nodig om de waarden te zien. Onze gids voor het begrijpen van Python-lijsten gaat uitgebreid in op die stijl. map leest nog steeds goed met een bestaande benoemde functie, zoals in map(str.strip, lines).
verminderen
functools.reduce combineert items tot één enkele waarde, met een doorlopend resultaat:
from functools import reduce
reduce(lambda acc, n: acc + n, nums, 0) # 21
sum(nums) # 21
Voor gewone taken, zoals totalen, gebruikt u een ingebouwde functie zoals sum, max of any. Bewaar reduce voor zeldzamere gevallen, en overweeg een gewone lus als de lambda er ingewikkeld uitziet.
Condities in een lambda
U kunt geen if-instructie in een lambda gebruiken, maar u kunt wel een voorwaardelijke expressie gebruiken:
label = lambda total: "large" if total >= 1000 else "small"
label(1200), label(300)
# ('large', 'small')
Eén voorwaarde is prima. Zodra je ze begint te nesten, moeten lezers hard werken, wat een duidelijk teken is om over te schakelen naar een def met gewone if uitspraken.
Lambda’s die functies retourneren
Een functie kan een lambda creëren en retourneren die een waarde uit zijn omgeving onthoudt:
def multiplier(n):
return lambda x: x * n
double = multiplier(2)
double(7) # 14
Dit werkt vanwege sluitingen, die in ons artikel over JavaScript-sluitingen in een andere taal worden uitgelegd. Python’s functools.partial biedt een andere manier om argumenten vooraf in te vullen.
De laatbindende valstrik
Dit overkomt uiteindelijk bijna iedereen. We hebben drie lambda’s in een lus gemaakt, in de verwachting dat elk zijn eigen nummer teruggeeft:
funcs = [lambda: i for i in range(3)]
[f() for f in funcs]
# [2, 2, 2]
Ze retourneren alle drie 2. Een lambda legt niet de waarde van i vast wanneer deze wordt gemaakt. Het zoekt de variabele op wanneer deze aangeroepen wordt, en tegen die tijd is de lus afgelopen, waardoor i op 2 blijft staan. De gebruikelijke oplossing is om de waarde als standaardargument vast te leggen, aangezien standaardwaarden worden geëvalueerd tijdens de definitie:
funcs = [lambda i=i: i for i in range(3)]
[f() for f in funcs]
# [0, 1, 2]
Dit is niet uniek voor lambda’s, aangezien een def in een lus zich op dezelfde manier gedraagt. Het komt alleen vaker voor bij lambda’s, omdat ze zo vaak in loops worden gemaakt, zoals bij het koppelen van knopcallbacks.
Tip: Als je een functie per item nodig hebt, bedenk dan of je überhaupt veel functies nodig hebt. Vaak is een enkele functie die het item als argument gebruikt, duidelijker en wordt de valstrik volledig vermeden.
Opzoektabellen met kleine functies
Lambda’s passen netjes in een woordenboek dat namen toewijst aan kleine operaties:
ops = {
"add": lambda a, b: a + b,
"sub": lambda a, b: a - b,
}
ops["sub"](10, 3) # 7
Dit kan een lange keten van if en elif vervangen. De gids Python-woordenboek behandelt meer woordenboekpatronen, en de module operator biedt al operator.add en operator.sub.
Grenzen van lambda’s
- Slechts één expressie. Geen toewijzingen met
=, geen lussen en geentryblokken. - Geen verklaringen. Het schrijven van
lambda x: return xmislukt met eenSyntaxError, zoals onze test heeft bevestigd. - Geen docstring- of typehints. Tools en lezers krijgen minder hulp.
- Hardere foutopsporing. Fouten verwijzen naar
<lambda>in plaats van naar een nuttige naam.
Lambda’s kunnen natuurlijk nog steeds uitzonderingen opleveren. Het afhandelen hiervan werkt hetzelfde als voor elke functie, zoals beschreven in Afhandeling van Python-uitzonderingen.
Wanneer mag u geen lambda gebruiken?
| Situatie | Betere keuze |
|---|---|
| Door het aan een naam te koppelen | zeker |
| Logica heeft meer dan één regel nodig | zeker |
| Een lijst transformeren of filteren | Een lijstbegrip |
| Optellen of een maximum vinden | sum, max, min |
| Een item of attribuut verkrijgen | operator.itemgetter of attrgetter |
| Dezelfde lambda komt op meerdere plaatsen voor | Een benoemde functie die u kunt testen |
Dat laatste punt is van belang. Logica die de moeite waard is om opnieuw te gebruiken, is het testen waard, en een benoemde functie is veel gemakkelijker te testen, zoals onze pytest-tutorial laat zien.
Tot slot
Een goede lambda is kort genoeg om in één oogopslag te lezen en wordt één keer gebruikt, meestal als argument. Sorteersleutels zijn het klassieke voorbeeld. Om uw eigen code te controleren, zoekt u naar = lambda en zet u deze om in benoemde functies. Kijk dan naar map of filter met een lambda en kijk of een begrip beter leest.
Veelgestelde vragen
Wat is een lambda-functie in Python?
Het is een kleine anonieme functie gemaakt met het trefwoord lambda. Er zijn argumenten nodig en retourneert de waarde van een enkele expressie, zonder naam of return-instructie.
Kan een Python lambda meerdere regels hebben?
Nee. Een lambda is beperkt tot één uitdrukking. Je kunt het over regels tussen haakjes verdelen, maar het kan nog steeds geen instructies bevatten, dus gebruik def voor complexere logica.
Kan ik if anders in een lambda gebruiken?
U kunt een voorwaardelijke expressie gebruiken, zoals lambda x: “groot” als x > 10 anders “klein”. Een if-statement met een blok is niet toegestaan.
Zijn lambda’s sneller dan normale functies?
Niet zinvol. Beide creëren hetzelfde soort functieobject. Kies tussen deze vanwege de leesbaarheid, niet vanwege de prestaties.
Moet ik een kaart met lambda of een lijstbegrip gebruiken?
De meeste Python-ontwikkelaars geven de voorkeur aan een lijstbegrip vanwege de leesbaarheid. map is redelijk als je al een benoemde functie hebt, zoals map(str.strip, lines).
Blijf leren
Hulp nodig met testen, WordPress of SEO?
We helpen teams betere software te leveren en hun sites te laten groeien. Vertel ons waar u mee bezig bent en wij stellen een duidelijke volgende stap voor.
Meer handleidingen over testen, AI en moderne ontwikkeling
Genoten van dit artikel? Kies een onderwerp en ga direct naar onze nieuwste tutorials.
AI-hallucinaties uitgelegd: waarom taalmodellen dingen verzinnen en hoe ze te verminderen
AI-hallucinaties uitgelegd: wat ze zijn, waarom taalmodellen ze produceren, veelvoorkomende typen, hoe je ze kunt verminderen met aarding en aanwijz…
Lees artikel →DevOpsOmgevingsvariabelen uitgelegd: .env-bestanden, geheimen en configuratie goed gedaan
Omgevingsvariabelen uitgelegd met Python-voorbeelden die we hebben uitgevoerd: ze lezen en instellen, waarom elke waarde een string is, .env-bestand…
Lees artikel →SoftwareontwikkelingAPI-snelheidsbeperking uitgelegd: algoritmen, headers en afhandeling van 429-fouten
API-snelheidsbeperking uitgelegd met een simulatie die we hebben uitgevoerd: token-bucket, vast venster, schuifvenster, 429 reacties, headers van sn…
Lees artikel →TestautomatiseringSpotten in Python: unittest.mock, patch en de fouten die tests doen liegen
Spotten in Python met unittest.mock, getest: Mock en return_value, side_effect, patchen waar een naam wordt gebruikt, spec en autospec, spotdatums e…
Lees artikel →SoftwaretestenCodedekking uitgelegd: lijn versus filiaaldekking en wat 100% werkelijk betekent
Codedekking uitgelegd met een echte dekking.py-run: dekking van lijnen, vertakkingen en condities, een rapport lezen, waarom 100% dekking nog steeds…
Lees artikel →Databases & SQLDELETE versus TRUNCATE versus DROP in SQL: verschillen, terugdraaien en wanneer elk te gebruiken
DELETE versus TRUNCATE versus DROP uitgelegd met geteste SQL: wat elk verwijdert, terugdraaien, triggers, identiteitsreset, snelheid en hoe PostgreS…
Lees artikel →Databases & SQLSQL-weergaven uitgelegd: creëer, gebruik en vermijd de valkuilen, met voorbeelden
SQL-weergaven uitgelegd met query's die we hebben uitgevoerd: een weergave maken, live resultaten, kolommen verbergen, prestaties, bijwerkbare en ge…
Lees artikel →SoftwareontwikkelingTypeScript-interface versus type: echte verschillen, getest met de compiler
TypeScript-interface versus type, gecontroleerd met de echte compiler: wat beide kunnen doen, wat slechts één kan doen, samenvoegen van declaraties,…
Lees artikel →SoftwareontwikkelingPython *args en **kwargs uitgelegd: flexibele functies met duidelijke voorbeelden
Python *args en **kwargs uitgelegd met code die we hebben uitgevoerd: in- en uitpakken, parametervolgorde, argumenten die alleen trefwoorden en posi…
Lees artikel →SoftwareontwikkelingPython Lambda-functies: syntaxis, echt gebruik en wanneer u ze niet moet gebruiken
Python lambda-functies uitgelegd met code die we hebben uitgevoerd: syntaxis, sorteren met sleutel, kaart en filter, sluitingen, de laat-bindende va…
Lees artikel →Kunstmatige intelligentieWat zijn AI-agenten? Hoe ze werken, met een eenvoudige agentloop die u kunt uitvoeren
Wat zijn AI-agenten? Een duidelijke gids voor de agentenlus, tools, geheugen en vangrails, met een kleine Python-lus die we hebben uitgevoerd, echte…
Lees artikel →DevOpsMonitoring versus waarneembaarheid: het echte verschil, met logboeken, statistieken en sporen
Monitoring versus waarneembaarheid uitgelegd: bekende en onbekende fouten, logboeken, statistieken en sporen, een walkthrough voor afrekenincidenten…
Lees artikel →DevOpsDocker-volumes versus bindingsmounts: bewaar containergegevens op de juiste manier
Docker-volumes versus bind-mounts uitgelegd: waarom containergegevens verdwijnen, benoemde volumes, bind-mounts, tmpfs, Compose-voorbeelden, back-up…
Lees artikel →TestautomatiseringTDD versus BDD: belangrijkste verschillen, één functie die op beide manieren is gebouwd en wanneer deze moet worden gebruikt
TDD versus BDD uitgelegd met één kortingsfunctie die in beide richtingen is gebouwd: rood-groen-refactor met code die we hebben uitgevoerd, gegeven-…
Lees artikel →SoftwareontwikkelingGit merge vs rebase: verschillen, voorbeelden en wanneer je wat gebruikt
Git merge vs rebase uitgelegd met echte logoutput, een vergelijkingstabel, de gouden regel van rebase en een veilige teamwerkwijze.
Lees artikel →SoftwareontwikkelingPython list comprehension: syntaxis, voorbeelden en wanneer je het vermijdt
Python list comprehension uitgelegd: syntaxis, filteren, if-else, geneste lussen, gemeten tijden en wanneer een gewone for-lus beter is.
Lees artikel →Databases & SQLSQL JOIN uitgelegd met voorbeelden (Inner, Left, Right, Full)
Begrijp SQL joins stap voor stap met voorbeeldtabellen en queries: INNER, LEFT, RIGHT, FULL, CROSS en SELF, plus veelgemaakte fouten en prestatietips.
Lees artikel →