# Hoe lambda-functies te gebruiken in Python

Lambda-functies worden **al** sinds Python 1.0 **gebruikt voor functioneel programmeren**. De laatste jaren zijn er echter andere technieken populairder geworden, die lambda’s grotendeels hebben vervangen. Toch zijn er nog steeds een aantal gespecialiseerde toepassingen voor lambda’s die ervaren Python-programmeurs moeten kennen.

## Wat zijn lambda-functies in Python?

In Python **verwijst een lambda-functie naar een anonieme functie**. Python gebruikt het sleutelwoord `lambda` om een lambda-functie te maken. Een lambda-expressie bestaat uit het sleutelwoord `lambda`, gevolgd door een lijst met argumenten, een dubbele punt en een enkele expressie. De expressie wordt voorzien van de argumenten en geëvalueerd wanneer de lambda-functie wordt aangeroepen:

```none
lambda argument: expression
```

Functies zijn een fundamenteel taalconstruct in bijna elke programmeertaal en vormen de kleinste herbruikbare eenheid van code. **Functies in Python worden** doorgaans **gedefinieerd met het sleutelwoord `def`**. Als voorbeeld laten we u de kwadratische functie zien, die een getal met zichzelf vermenigvuldigt:

```python
# Define square function
def square(num):
    return num * num
# Show that it works
assert square(9) == 81
```

Het sleutelwoord `def` is een bekende manier om functies in Python te definiëren, maar de taal heeft ook lambda’s. Dit zijn **anonieme functies die een uitdrukking met parameters definiëren**. Lambda’s kunnen overal worden gebruikt waar een functie wordt verwacht of aan een naam kan worden toegewezen. Hier ziet u de lambda-uitdrukking die gelijk is aan de kwadratische functie:

```python
# Create square function
squared = lambda num: num * num
# Show that it works
assert squared(9) == 81
```

Opmerking In Python verwijst een lambda-functie naar een functie die is gemaakt met het sleutelwoord `lambda`. Lambda is niet de naam van een specifieke functie en ook geen van de Python-operatoren.

### Wat is het verschil tussen lambda en def?

Het lijkt misschien vreemd dat je in Python functies kunt maken met zowel `lambda` als `def`. `Lambda` is echter **geen aparte functie**, maar gewoon een andere manier om lokaal korte functies te maken. Elke functie die met `lambda` wordt gemaakt, kan ook met `def` worden gemaakt. Omgekeerd is dit echter niet het geval.

Op syntactisch niveau zijn `lambda` en `def` beide sleutelwoorden. Een belangrijk verschil tussen beide is **de strikte scheiding tussen statements en expressies** in Python. Statements zijn stappen in de uitvoering van code, terwijl expressies worden geëvalueerd tot een waarde.

`Def` begint een statement, of meer specifiek een samengesteld **statement, dat verdere statements bevat**. Er mogen alleen `return` statements voorkomen binnen een `def` statement. Een `return` statement retourneert een waarde wanneer de functie gedefinieerd met `def` wordt aangeroepen.

In tegenstelling tot de `def` -instructie **begint`lambda` een expressie die geen instructies mag bevatten**. De lambda-expressie neemt een of meer argumenten en retourneert een anonieme functie. Wanneer de lambda-functie wordt aangeroepen, wordt de expressie die erin staat geëvalueerd met de doorgegeven argumenten en wordt deze geretourneerd.

### Wat zijn de beperkingen van Python’s lambda-expressies?

Python heeft het nut van lambda-functies bewust beperkt, omdat het meestal **beter** is **om functies een naam te geven**. Dit dwingt programmeurs om na te denken over de betekenis van de functie en om onderdelen duidelijk te onderscheiden.

Lambdas kunnen geen instructies bevatten, in tegenstelling tot de body van een functie die is gedefinieerd met het sleutelwoord `def`. Het is daarom **niet mogelijk om `if`, `for`, enz. te gebruiken in een lambda-functie**. Het is ook niet mogelijk om een uitzondering te activeren, omdat hiervoor een `raise` nodig is.

Lambda-functies in Python kunnen één enkele expressie bevatten die wordt geëvalueerd wanneer deze wordt aangeroepen. **Type-annotaties kunnen niet worden gebruikt** binnen de lambda-expressie. Tegenwoordig maken de meeste gebruiksscenario’s van lambda-functies in Python gebruik van andere technieken, zoals comprehensions.

## Verschillende toepassingen voor lambda-functies in Python

Lambda’s **zijn afgeleid van functioneel programmeren**. In sommige talen, zoals JavaScript, worden anonieme functies veel gebruikt zonder dat daarvoor een speciaal trefwoord nodig is. In Python worden lambda-expressies gebruikt om lokaal kleine functies te maken. Hieronder bespreken we de meest nuttige toepassingen ervan.

### Hoe hogere orde functies in Python te vullen met lambda’s

Lambdas worden vaak gebruikt met **hogere-orde functies zoals `map()`, `filter()` en `reduce()`**. Dankzij lambdas kunnen de elementen van een iterable worden getransformeerd zonder gebruik te maken van loops. Hogere-orde functies zijn functies die functies als parameters nemen of een functie retourneren.

De functie `map()` neemt een functie en een iterable als parameters. Het voert de functie uit voor elk element van de iterable. Laten we eens proberen om kwadraten te genereren. We gebruiken de functie `map()` en **geven een lambda-expressie als argument door**, die de kwadraatfunctie genereert. De kwadraatfunctie wordt toegepast op elk element van de lijst met `map()`:

```python
nums = [3, 5, 7]
# Square numbers using `map()` and `lambda`
squares = map(lambda num: num ** 2, nums)
# Show that it works
assert list(squares) == [9, 25, 49]
```

Opmerking Vanaf Python 3.0 retourneren de functies `map()` en `filter()` een iterable in plaats van een lijst. Een `list()` -aanroep wordt gebruikt binnen de `assert` statements om iterables uit te pakken in een lijst.

Lijstcomprehensions bieden een **modernere benadering voor het verwerken van iterables**. In plaats van onze toevlucht te nemen tot `map()` en een lambda-functie te genereren, kunnen we de bewerking direct beschrijven:

```python
nums = [3, 5, 7]
# Square numbers using list comprehension
squares = [num ** 2 for num in nums]
# Show that it works
assert squares == [9, 25, 49]
```

De functie `filter()` kan worden gebruikt om **de elementen van een iterable te filteren**. We kunnen ons voorbeeld uitbreiden om alleen even kwadraten te genereren:

```python
# List of numbers 1-4
nums = [1, 2, 3, 4]
# Square each number
squares = list(map(lambda num: num ** 2, nums))
# Filter out the even squares
even_squares = filter(lambda square: square % 2 == 0, squares)
# Show that it works
assert list(even_squares) == [4, 16]
```

We laten zien dat het gebruik van lijstcomprehension de voorkeur heeft om **hetzelfde resultaat te genereren zonder gebruik te maken van lambda’s en hogere-ordefuncties**. Het `if` van de comprehension wordt gebruikt om de even getallen uit de gegenereerde kwadraten te filteren:

```python
# List of numbers 1-4 squared
squares = [num ** 2 for num in range(1, 5)]
# Filter out the even squares
even_squares = [square for square in squares if square % 2 == 0]
# Show that it works
assert even_squares == [4, 16]
```

Opmerking De functie `reduce()` van Python is sinds Python 3.0 niet meer opgenomen in de standaardbibliotheek. Deze functie is te vinden in de module `functools`.

### Hoe je belangrijke functies in Python implementeert met lambda’s

Comprehensions hebben de klassieke hogere-orde functies `map()` en `filter()` in Python grotendeels vervangen. **Er kunnen** echter **sleutelfuncties worden gebruikt om de volledige kracht van lambda’s te demonstreren**.

De Python-vergelijkingsfuncties `sorted()`, `min()` en `max()` werken op iterables. Elk element van de iterable wordt bij het aanroepen onderworpen aan een vergelijking. De drie functies nemen een sleutelfunctie als optionele parameter `key`. De sleutelfunctie wordt voor elk element aangeroepen en retourneert een sleutelwaarde voor de vergelijkingsbewerking.

Laten we eens kijken naar het volgende probleem. We hebben een map met afbeeldingsbestanden waarvan de namen zijn toegewezen aan een Python-lijst. We willen **de lijst sorteren**. De bestandsnamen beginnen allemaal met `img`, gevolgd door een cijfer:

```python
# List of image file names
images = ['img1', 'img2', 'img30', 'img3', 'img22', 'img100']
```

Als we de functie `sorted()` van Python gebruiken, **wordt de lexicografische volgorde gebruikt**. Hierbij worden opeenvolgende cijfers als afzonderlijke getallen behandeld. Daardoor worden de getallen `['1', '2', '100']` in de volgorde `['1', '100', '2']` geplaatst. Het resultaat is niet wat we verwachten:

```python
# Sort using lexicographic order
sorted_image = sorted(images)
# Show that it works
assert sorted_image == ['img1', 'img100', 'img2', 'img22', 'img3', 'img30']
```

We **geven een `lambda` door die een sleutelfunctie produceert** om ervoor te zorgen dat het sorteren correct verloopt. De sleutelfunctie haalt het numerieke deel van een bestandsnaam eruit, dat door `sorted()` als sleutel wordt gebruikt:

```python
# Extract numeric component and sort as integers
sorted_image = sorted(images, key=lambda name: int(name[3:]))
# Show that it works
assert sorted_image == ['img1', 'img2', 'img3', 'img22', 'img30', 'img100']
```

De sleutelfunctie wordt lokaal en slechts één keer gebruikt. Het is niet nodig om hiervoor een extra benoemde functie te definiëren. **Lambda’s zijn de juiste manier om sleutelfuncties te maken**. Laten we nog twee voorbeelden bekijken.

Net als `sorted()` hebben de ingebouwde Python-functies `min()` en `max()` een optionele sleutelfunctie. De functies zoeken het kleinste en grootste element in een lijst of andere iterable. Het **kleinste of grootste element is een kwestie van definitie** en kan worden gespecificeerd met behulp van de sleutelfunctie.

Het is duidelijk wat wordt bedoeld met het kleinste of grootste element voor lijsten met eenvoudige waarden, zoals een lijst met getallen. In dit geval hebben we geen speciale sleutelfunctie nodig:

```python
nums = [42, 69, 51, 13]
assert min(nums) == 13
assert max(nums) == 69
```

Opmerking Als er geen sleutelfunctie wordt doorgegeven, wordt de identiteitsfunctie `f(x) = x` als standaard gebruikt. Dit kan eenvoudig worden gedefinieerd als een Python-lambda met `lambda x: x`.

Maar wat als elk element van een iterable meerdere datums bevat? Laten we eens kijken naar een lijst met woordenboeken die mensen met hun namen en leeftijden weergeven. Wat is het **criterium voor `min()` en `max()`** bij het bepalen van het kleinste en grootste element? Hier komt een sleutelfunctie goed van pas.

We hebben **voorbeeldgegevens** nodig om te illustreren hoe belangrijke functies werken. Laten we een functie `Person()` maken die als constructor dient:

```python
# Constructor function for dict representing a person
def Person(name, age):
    return {'name': name, 'age': age}
# Check that it works as expected
assert Person('Jim', 42) == {'name': 'Jim', 'age': 42}
```

We **maken een lijst van personen** met behulp van onze constructor-functie:

```python
# Create list of people
people = [person('Jim', 42), person('Jack', 51), person('John', 69)]
```

We zoeken de oudste persoon met behulp van de `max()` call. Dit **genereert een sleutelfunctie** met behulp van de lambda-expressie, die een person dict neemt en daaruit de leeftijd haalt als vergelijkingselement:

```python
# Find the oldest person
oldest = max(people, key=lambda person: person['age'])
# Check that it works
assert oldest == Person('John', 69)
```

De aanpak werkt precies hetzelfde voor de functie `min()`. In dit geval **definiëren** we **de sleutelfunctie buiten de aanroep `min()`** en gebruiken we opnieuw een lambda-expressie. Dit verbetert de leesbaarheid en is de moeite waard als de sleutelfunctie meerdere lokale toepassingen heeft:

```python
# Define key function to compare people by age
by_age = lambda person: person['age']
# Find the youngest person
youngest = min(people, key=by_age)
# Check that it works
assert youngest == Person('Jim', 42)
```

### Hoe sluitingen maken met Python-lambda’s

Python-lambda’s worden ook gebruikt bij het definiëren van closures. Dit zijn functies die door andere functies worden gemaakt en een waarde opslaan. Closures kunnen worden **gebruikt om families** van vergelijkbare functies **te maken**. We laten een veelvoorkomend voorbeeld zien waarbij machtsfuncties worden gemaakt.

Machtfuncties nemen een argument en verheffen dit tot een macht. De kwadratische functie `f(x) = x ^ 2` en de kubische functie `f(x) = x ^ 3` zijn bekende voorbeelden. Willekeurige machtfuncties kunnen worden gegenereerd als sluitingen met behulp van een constructorfunctie. We gebruiken een lambda-expressie, wat betekent dat we geen interne functie met een naam hoeven te definiëren:

```python
# Define constructor function for power functions
def power(n):
    return lambda num: num ** n
# Create square and cubic functions as closures
square = power(2)
cubic = power(3)
# Show that it works
assert square(10) == 100
assert cubic(10) == 1000
```

### Hoe gebruik je een onmiddellijk aangeroepen functie-expressie (IIFE) met Python-lambda’s?

IIFE, uitgesproken als ‘iffy’, is een **bekend patroon in JavaScript**. Het houdt in dat een anonieme functie wordt gedefinieerd en onmiddellijk wordt uitgevoerd.

**Lambda’s kunnen worden gebruikt als IIFE’s**, hoewel ze vanwege beperkingen in Python niet erg nuttig zijn. We hoeven alleen maar haakjes rond de lambda-expressie te plaatsen:

```python
(lambda num: num * num)
```

En nog een paar haakjes met daarin het argument of de argumenten:

```python
assert (lambda num: num * num)(3) == 9
```

Tip Voor beginners in Python raden we aan om onze Python-tutorial te bekijken.


This is a markdown version of: [https://www.ionos.com/nl-be/digitalguide/websites/webontwikkeling/lambda-functies-in-python/](https://www.ionos.com/nl-be/digitalguide/websites/webontwikkeling/lambda-functies-in-python/) for AI/LLM consumption.