# Sådan bruges lambda-funktioner i Python

Lambda-funktioner har været en **metode til funktionel programmering** siden Python 1.0. I de senere år har andre teknikker imidlertid vundet større popularitet og i vid udstrækning erstattet lambdaer. Ikke desto mindre er der stadig nogle specialiserede anvendelser for lambdaer, som kyndige Python-programmører bør kende til.

## Hvad er lambda-funktioner i Python?

I Python **refererer lambda-funktionen til en anonym funktion**. Python bruger nøgleordet `lambda` til at oprette en lambda-funktion. Et lambda-udtryk består af nøgleordet `lambda` efterfulgt af en liste over argumenter, et kolon og et enkelt udtryk. Udtrykket forsynes med argumenterne og evalueres, når lambda-funktionen kaldes:

```none
lambda argument: expression
```

Funktioner er en grundlæggende sprogkonstruktion i næsten alle programmeringssprog, og de repræsenterer den mindste genanvendelige enhed af kode. Typisk **defineres funktioner i Python med nøgleordet `def`**. Vi viser dig kvadratfunktionen, der multiplicerer et tal med sig selv, som et eksempel:

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

Nøgleordet `def` er en velkendt måde at definere funktioner på i Python, men sproget har også lambdas. Dette er **anonyme funktioner, der definerer et udtryk med parametre**. Lambdas kan bruges overalt, hvor en funktion forventes eller kan tildeles et navn. Du kan se lambda-udtrykket, der svarer til kvadratfunktionen, her:

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

Note I Python henviser lambda-funktionen til en funktion, der er oprettet med nøgleordet `lambda`. Lambda er ikke navnet på en bestemt funktion og er heller ikke en af Python-operatorerne.

### Hvad er forskellen mellem lambda og def?

Det kan virke underligt, at Python lader dig oprette funktioner med både `lambda` og `def`. Men `Lambda` er **ikke en egen funktion**, men blot en anden måde at oprette korte funktioner lokalt på. Alle funktioner, der oprettes med `lambda`, kan også oprettes med `def`. Det gælder dog ikke omvendt.

På det syntaktiske niveau er `lambda` og `def` begge nøgleord. En vigtig forskel mellem dem er Pythons **strenge adskillelse af sætninger og udtryk**. Sætninger er trin i udførelsen af kode, mens udtryk evalueres til en værdi.

`Def` indleder en sætning, eller mere specifikt en sammensat **sætning, som indeholder yderligere sætninger**. Der må kun forekomme `return` sætninger inden for en `def` sætning. En `return` sætning returnerer en værdi, når den funktion, der er defineret med `def`, kaldes.

I modsætning til `def` **starter`lambda` et udtryk, der ikke kan indeholde nogen sætninger**. Lambda-udtrykket tager et eller flere argumenter og returnerer en anonym funktion. Når lambda-funktionen kaldes, evalueres det udtryk, den indeholder, med de overførte argumenter, og det returneres.

### Hvad er begrænsningerne ved Pythons lambda-udtryk?

Python har bevidst begrænset nytten af lambda-funktioner, da det normalt er **bedre at navngive funktioner**. Dette tvinger programmører til at tænke over funktionens betydning og skelne klart mellem de forskellige dele.

Lambdaer kan ikke indeholde instruktioner, i modsætning til kroppen af en funktion defineret med nøgleordet `def`. Det er derfor **ikke muligt at bruge `if`, `for` osv. i en lambda-funktion**. Det er heller ikke muligt at udløse en undtagelse, da dette kræver en `raise`.

Lambda-funktioner i Python kan indeholde et enkelt udtryk, der evalueres, når det kaldes. **Typeannotationer kan ikke bruges** i lambda-udtrykket. I dag bruger de fleste anvendelsestilfælde af lambda-funktioner i Python andre teknikker, såsom comprehensions.

## Forskellige anvendelser af lambda-funktioner i Python

Lambdaer **stammer fra funktionel programmering**. I nogle sprog, såsom JavaScript, bruges anonyme funktioner i vid udstrækning uden behov for et særligt nøgleord. I Python bruges lambda-udtryk til at oprette små funktioner lokalt. Vi gennemgår deres mest nyttige anvendelser nedenfor.

### Sådan udfyldes højere ordensfunktioner i Python med lambdas

Lambdaer bruges ofte sammen med **højere ordensfunktioner som `map()`, `filter()` og `reduce()`**. Elementerne i en iterabel kan transformeres uden brug af sløjfer takket være lambdaer. Højere ordensfunktioner er funktioner, der tager funktioner som parametre eller returnerer en funktion.

Funktionen `map()` tager en funktion og en iterabel som parametre. Den udfører funktionen for hvert element i den iterable. Lad os prøve at generere kvadratnumre. Vi bruger funktionen `map()` og **sender et lambda-udtryk som argument**, hvilket genererer kvadratfunktionen. Kvadratfunktionen anvendes på hvert element i listen med `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]
```

Note Fra og med Python 3.0 returnerer funktionerne `map()` og `filter()` en iterabel i stedet for en liste. Et `list()` -kald bruges i `assert` -sætningerne til at udpakke iterabler til en liste.

List comprehensions tilbyder en mere **moderne tilgang til behandling af iterables**. I stedet for at ty til `map()` og generere en lambda-funktion, kan vi beskrive operationen direkte:

```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]
```

Funktionen `filter()` kan bruges til **at filtrere elementerne i en iterabel**. Vi kan udvide vores eksempel til kun at generere lige kvadratnumre:

```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]
```

Vi viser den foretrukne tilgang, hvor man bruger listeforståelse til **at generere det samme resultat uden at bruge lambdas og højere ordensfunktioner**. Den `if` del af forståelsen bruges til at filtrere de lige tal fra de genererede kvadratnumre:

```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]
```

Note Pythons `reduce()` -funktion er ikke blevet inkluderet i standardbiblioteket siden Python 3.0. Denne funktion kan findes i `functools` -modulet.

### Sådan implementeres nøglefunktioner i Python med lambdas

Comprehensions har i vid udstrækning erstattet de klassiske højere ordensfunktioner `map()` og `filter()` i Python. **Nøglefunktioner kan** dog **bruges til at demonstrere lambdas fulde styrker**.

Python-sammenligningsfunktionerne `sorted()`, `min()` og `max()` fungerer på iterable. Hvert element i iterable underkastes en sammenligning, når det kaldes. De tre funktioner tager en nøglefunktion som en valgfri `key` parameter. Nøglefunktionen kaldes for hvert element og returnerer en nøgleværdi til sammenligningsoperationen.

Lad os se på følgende problem. Vi har en mappe med billedfiler, hvor navnene er knyttet til en Python-liste. Vi vil **sortere listen**. Alle filnavne starter med `img` efterfulgt af et tal:

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

Hvis vi bruger Pythons `sorted()`, **anvendes den leksikografiske rækkefølge**. Her behandles på hinanden følgende cifre som enkeltcifre. Derfor placeres tallet `['1', '2', '100']` i rækkefølgen `['1', '100', '2']`. Resultatet er ikke som forventet:

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

Vi **sender et `lambda`, der producerer en nøglefunktion** for at sikre, at sorteringen er korrekt. Nøglefunktionen udtrækker den numeriske del af et filnavn, som bruges som nøgle af `sorted()`:

```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']
```

Nøglefunktionen bruges lokalt og kun én gang. Det er ikke nødvendigt at definere en ekstra navngiven funktion til den. **Lambdas er den korrekte måde at oprette nøglefunktioner på**. Lad os se på to flere eksempler.

Ligesom `sorted()` tager de indbyggede Python-funktioner `min()` og `max()` en valgfri nøglefunktion. Funktionerne finder det mindste og største element i en liste eller anden iterabel. Det **mindste eller største element er et spørgsmål om definition** og kan specificeres ved hjælp af nøglefunktionen.

Det er klart, hvad der menes med det mindste eller største element for lister med enkle værdier, såsom en liste med tal. I dette tilfælde har vi ikke brug for en særlig nøglefunktion:

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

Note Hvis der ikke overføres nogen nøglefunktion, bruges identitetsfunktionen `f(x) = x` som standard. Dette kan nemt defineres som en Python-lambda med `lambda x: x`.

Men hvad nu hvis hvert element i en iterabel indeholder flere datoer? Lad os forestille os en liste med ordbøger, der repræsenterer personer med deres navne og alder. Hvad er **kriteriet for `min()` og `max()`**, når man skal beslutte, hvilket element der er det mindste og det største? Det er her, en nøglefunktion er nyttig.

Vi har brug for **eksempeldata** for at illustrere, hvordan nøglefunktioner fungerer. Lad os oprette en funktion `Person()`, der fungerer som en konstruktør:

```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}
```

Vi **opretter en liste over personer** ved hjælp af vores konstruktorfunktion:

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

Vi finder den ældste person ved hjælp af `max()`. Dette **genererer en nøglefunktion** ved hjælp af lambda-udtrykket, som tager en person-dict og udtrækker alderen fra den som et sammenligningselement:

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

Tilgangen fungerer nøjagtigt på samme måde for funktionen `min()`. I dette tilfælde **definerer** vi **nøglefunktionen uden for `min()` kaldet** og bruger igen et lambda-udtryk. Dette forbedrer læsbarheden og er værdifuldt, hvis nøglefunktionen har flere lokale anvendelser:

```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)
```

### Sådan oprettes lukninger med Python-lambdaer

Python-lambdaer bruges også til at definere lukninger. Det er funktioner, der oprettes af andre funktioner og gemmer en værdi. Lukninger kan **bruges til at oprette familier** af lignende funktioner. Vi viser et almindeligt eksempel, hvor der oprettes potensfunktioner.

Potensfunktioner tager et argument og eksponerer det. Kvadratfunktionen `f(x) = x ^ 2` og kubikfunktionen `f(x) = x ^ 3` er velkendte eksempler. Vilkårlige potensfunktioner kan genereres som lukninger ved hjælp af en konstruktorfunktion. Vi bruger et lambda-udtryk, hvilket betyder, at vi ikke behøver at definere en indre navngivet funktion:

```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
```

### Sådan bruges IIFE (Immediately Invoked Function Expression) med Python-lambdaer

IIFE, udtalt ‘iffy’, er et **kendt mønster i JavaScript**. Det indebærer at definere en anonym funktion og udføre den med det samme.

**Lambdaer kan bruges som IIFE’er**, selvom de ikke er særlig nyttige på grund af begrænsninger i Python. Vi behøver kun at sætte parenteser omkring lambda-udtrykket:

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

Og endnu et par parenteser, der indeholder argumentet/argumenterne:

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

Tip For begyndere i Python anbefaler vi, at du kigger på vores Python-tutorial.


This is a markdown version of: [https://www.ionos.com/da-dk/digitalguide/websteder/webudvikling/lambda-funktioner-i-python/](https://www.ionos.com/da-dk/digitalguide/websteder/webudvikling/lambda-funktioner-i-python/) for AI/LLM consumption.