# Kuidas kasutada lambda-funktsioone Pythonis

Lambda-funktsioonid on olnud **funktsionaalse programmeerimise meetod** alates Python 1.0 **versioonist**. Viimastel aastatel on aga populaarsust kogunud teised tehnikad, mis on lambdad suures osas asendanud. Siiski on lambdadele veel mõned spetsiifilised kasutusvaldkonnad, mida kogenud Python-programmeerijad peaksid teadma.

## Mis on lambda-funktsioonid Pythonis?

Pythonis **viitab lambda-funktsioon anonüümsele funktsioonile**. Python kasutab lambda-funktsiooni loomiseks märksõna `lambda`. Lambda-väljend koosneb märksõnast `lambda`, millele järgneb argumentide loend, koolon ja üksik väljend. Väljendile antakse argumendid ja see hinnatakse lambda-funktsiooni kutsumisel:

```none
lambda argument: expression
```

Funktsioonid on peaaegu kõigi programmeerimiskeelte põhikonstruktsioonid ja need kujutavad endast väikseimat taaskasutatavat koodiühikut. Tavaliselt **määratletakse funktsioonid Pythonis märksõnaga `def`**. Näitame teile näiteena ruutfunktsiooni, mis korrutab arvu iseendaga:

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

`def` märksõna on tuntud viis funktsioonide määratlemiseks Pythonis, kuid keeles on ka lambdad. Need on **anonüümsed funktsioonid, mis määratlevad parameetritega avaldise**. Lambdasid saab kasutada kõikjal, kus oodatakse funktsiooni või kus neid saab nimele omistada. Siin näete ruutfunktsiooniga võrdväärset lambda-avaldist:

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

Note Pythonis viitab lambda-funktsioon funktsioonile, mis on loodud märksõnaga `lambda`. Lambda ei ole konkreetse funktsiooni nimi ega ka üks Python-operaatoritest.

### Mis vahe on lambda ja def vahel?

Võib tunduda veider, et Python võimaldab luua funktsioone nii `lambda` kui ka `def` abil. Siiski **ei** ole `Lambda` **omaette funktsioon**, vaid lihtsalt veel üks viis lühikeste funktsioonide loomiseks kohalikult. Iga `lambda` abil loodud funktsioon on võimalik luua ka `def` abil. Siiski ei kehti see vastupidi.

Süntaktilisel tasandil on `lambda` ja `def` mõlemad võtmesõnad. Üks oluline erinevus nende vahel on Pythoni **range lause ja avaldise eraldamine**. Laused on koodi täitmise etapid, avaldised aga väärtuseks hindamisel.

`Def` algab avaldus, täpsemalt **liitavaldus, mis sisaldab täiendavaid avaldusi**. `def` avalduses võib esineda ainult `return` avaldust. `return` avaldus tagastab väärtuse, kui kutsutakse `def` määratletud funktsiooni.

Erinevalt `def` lausest **algab`lambda` väljendiga, mis ei tohi sisaldada ühtegi lauset**. Lambda-väljend võtab vastu ühe või mitu argumenti ja tagastab anonüümse funktsiooni. Kui lambda-funktsioon kutsutakse, hinnatakse selles sisalduv väljend edastatud argumentidega ja see tagastatakse.

### Millised on Pythoni lambda-väljendite piirangud?

Python on teadlikult piiranud lambda-funktsioonide kasulikkust, kuna tavaliselt on **parem funktsioonidele nimed anda**. See sunnib programmeerijaid mõtlema funktsiooni tähenduse üle ja eristama selgelt selle osi.

Lambdad ei saa sisaldada juhiseid, erinevalt `def` märksõnaga määratletud funktsiooni kehast. Seetõttu **ei** ole **võimalik kasutada `if`, `for` jne lambda-funktsioonis.** Samuti ei ole võimalik käivitada erandit, kuna selleks on vaja `raise` avaldust.

Pythonis võivad lambda-funktsioonid sisaldada ühte avaldist, mis hinnatakse funktsiooni kutsumisel. Lambda-avaldises **ei saa kasutada tüübi märkusi**. Tänapäeval kasutatakse Pythonis lambda-funktsioonide enamikus kasutamisjuhtudes teisi tehnikaid, näiteks arusaamu.

## Lambda-funktsioonide erinevad kasutusviisid Pythonis

Lambdad **on tuletatud funktsionaalsest programmeerimisest**. Mõnes keeles, näiteks JavaScriptis, kasutatakse anonüümseid funktsioone laialdaselt ilma spetsiaalse märksõna vajaduseta. Pythonis kasutatakse lambda-väljendeid väikeste funktsioonide loomiseks kohalikult. Allpool vaatame läbi nende kõige kasulikumad rakendused.

### Kuidas täita Pythoni kõrgemate järjekordade funktsioone lambdadega

Lambdasid kasutatakse sageli **kõrgemate järjekordade funktsioonidega, nagu `map()`, `filter()` ja `reduce()`**. Lambdade abil saab iterable’i elemente teisendada ilma tsükleid kasutamata. Kõrgemate järjekordade funktsioonid on funktsioonid, mis võtavad parameetritena funktsioone või tagastavad funktsiooni.

Funktsioon `map()` võtab parameetritena vastu funktsiooni ja iterable’i. See käivitab funktsiooni iga iterable’i elemendi jaoks. Proovime genereerida ruutnumbreid. Kasutame funktsiooni `map()` ja **edastame argumendina lambda-väljendi**, mis genereerib ruutfunktsiooni. Ruutfunktsiooni rakendatakse iga loendi elemendi jaoks `map()` abil:

```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 Alates Python 3.0 versioonist tagastavad funktsioonid `map()` ja `filter()` loendi asemel iterable’i. `list()` kutsutakse `assert` avaldistes, et iterable’id loendisse lahti pakkida.

Loendite mõistmine pakub **kaasaegsemat lähenemisviisi iterable’ide töötlemiseks**. Selle asemel, et kasutada `map()` ja luua lambda-funktsioon, saame kirjeldada operatsiooni otse:

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

Funktsiooni `filter()` abil saab **filtreerida iterable’i elemente**. Me võime laiendada oma näidet, et genereerida ainult paarisarvulisi ruutnumbreid:

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

Näitame eelistatud lähenemisviisi, mille puhul kasutatakse loendi mõistmist, et **saada sama tulemus ilma lambdade ja kõrgemate järku funktsioonide kasutamiseta**. Mõistmise osa `if` kasutatakse, et filtreerida genereeritud ruutnumbrite hulgast välja paarisnumbrid:

```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 Pythoni funktsioon `reduce()` ei ole alates Python 3.0 versioonist standardteegis sisaldunud. See funktsioon on leitav moodulis `functools`.

### Kuidas rakendada Pythonis lambdade abil põhilisi funktsioone

Comprehensions on Pythonis suures osas asendanud klassikalised kõrgemate järjekordade funktsioonid `map()` ja `filter()`. Siiski **saab lambdade kõiki eeliseid demonstreerida võtmefunktsioonide abil**.

Pythoni võrdlusfunktsioonid `sorted()`, `min()` ja `max()` töötavad iterable’itega. Iga iterable’i element võrreldakse, kui funktsioon kutsutakse. Need kolm funktsiooni võtavad võtmefunktsiooni valikulise parameetrina `key`. Võtmefunktsioon kutsutakse iga elemendi jaoks ja see tagastab võrdlusoperatsiooni jaoks võtmeväärtuse.

Vaatleme järgmist probleemi. Meil on kaust pildifailidega, mille nimed on seotud Python-nimekirjaga. Soovime **nimekirja sorteerida**. Kõik failinimed algavad numbriga `img`, millele järgneb number:

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

Kui kasutame Pythoni funktsiooni `sorted()`, **kasutatakse leksikograafilist järjestust**. See käsitleb järjestikuseid numbreid ühe numbrina. Seega paigutatakse numbrid `['1', '2', '100']` järjestusse `['1', '100', '2']`. Tulemus ei ole selline, nagu ootame:

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

Me **edastame `lambda` väljendi, mis loob võtmefunktsiooni**, et tagada sorteerimise õigsus. Võtmefunktsioon eraldab failinime numbrilise osa, mida `sorted()` kasutab võtmena:

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

Võtmefunktsiooni kasutatakse kohalikult ja ainult üks kord. Selle jaoks pole vaja määratleda eraldi nimega funktsiooni. **Lambdad on õige viis võtmefunktsioonide loomiseks**. Vaadakem veel kahte näidet.

Nagu `sorted()`, võtavad sisseehitatud Python-funktsioonid `min()` ja `max()` vastu valikulise võtmefunktsiooni. Funktsioonid leiavad nimekirjast või muust iteratiivsetest elementidest väikseima ja suurima elemendi. **Väikseim või suurim element on määratluse küsimus** ja **seda** saab täpsustada võtmefunktsiooni abil.

Lihtsate väärtuste loendite puhul, näiteks numbrite loendite puhul, on selge, mida tähendab väikseim või suurim element. Sel juhul ei ole vaja spetsiaalset võtmefunktsiooni:

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

Note Kui võtmefunktsiooni ei edastata, kasutatakse vaikimisi identiteedifunktsiooni `f(x) = x`. Seda saab hõlpsasti defineerida Python lambda abil `lambda x: x`.

Aga mis siis, kui iterable’i iga element sisaldab mitut kuupäeva? Kujutlegem nimekirja, mis sisaldab inimeste nimesid ja vanuseid. Millised on **kriteeriumid `min()` ja `max()` puhul**, kui otsustatakse, milline on väikseim ja suurim element? Siin on kasulik võtmefunktsioon.

Vajame **näiteandmeid**, et illustreerida võtmefunktsioonide tööpõhimõtet. Loome funktsiooni `Person()`, mis toimib konstruktorina:

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

Me **loome inimeste nimekirja**, kasutades oma konstruktorifunktsiooni:

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

Leiame vanima isiku, kasutades `max()` kõnet. See **genereerib võtmefunktsiooni**, kasutades lambda-väljendit, mis võtab isiku sõnastiku ja ekstraktib sellest vanuse võrdluselemendina:

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

Sama lähenemisviis toimib ka funktsiooni `min()` puhul. Sel juhul **määratleme võtmefunktsiooni väljaspool `min()` kutsumist** ja kasutame taas lambda-väljendit. See parandab loetavust ja on kasulik, kui võtmefunktsioonil on mitu kohalikku kasutust:

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

### Kuidas luua sulgureid Python lambdas

Python lambdas kasutatakse ka sulgude määratlemisel. Need on funktsioonid, mis on loodud teiste funktsioonide poolt ja salvestavad väärtuse. Sulgude **abil** saab **luua** sarnaste funktsioonide **perekondi**. Näitame tavalist näidet, kus luuakse võimsusfunktsioonid.

Võimsusfunktsioonid võtavad argumendi ja tõstavad selle eksponendiks. Ruutfunktsioon `f(x) = x ^ 2` ja kuupfunktsioon `f(x) = x ^ 3` on tuntud näited. Konstruktorfunktsiooni abil saab luua suvalisi võimsusfunktsioone kui sulgumisi. Kasutame lambda-väljendit, mis tähendab, et meil ei ole vaja määratleda sisemist nimelist funktsiooni:

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

### Kuidas kasutada Python lambdas kohe käivitatavat funktsiooni väljendit (IIFE)

IIFE, hääldatakse „iffy”, on **JavaScriptis tuntud muster**. See hõlmab anonüümse funktsiooni määratlemist ja selle kohest täitmist.

**Lambdasid saab kasutada IIFE-dena**, kuigi need ei ole Pythoni piirangute tõttu eriti kasulikud. Me peame ainult lambda-väljendi ümber sulgudesse panema:

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

Ja veel üks sulgude paar, mis sisaldab argumenti (argumente):

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

Tip Pythoni algajatele soovitame tutvuda meie Pythoni õpetusega.


This is a markdown version of: [https://www.ionos.com/et-ee/digitalguide/veebisaidid/veebiarendus/lambda-funktsioonid-pythonis/](https://www.ionos.com/et-ee/digitalguide/veebisaidid/veebiarendus/lambda-funktsioonid-pythonis/) for AI/LLM consumption.