# Kaip naudoti lambda funkcijas Python kalboje

Lambda funkcijos yra **funkcinio programavimo metodas** nuo Python 1.0 **versijos**. Tačiau pastaraisiais metais kitos technikos tapo populiaresnės ir iš esmės pakeitė lambda funkcijas. Nepaisant to, vis dar yra keletas specializuotų lambda funkcijų naudojimo atvejų, kuriuos patyrę Python programuotojai turėtų žinoti.

## Kas yra lambda funkcijos Python kalboje?

Python kalboje **lambda funkcija reiškia anoniminę funkciją**. Python naudoja raktinį žodį `lambda`, kad sukurtų lambda funkciją. Lambda išraiška susideda iš raktinio žodžio `lambda`, po kurio eina argumentų sąrašas, dvitaškis ir viena išraiška. Išraiška pateikiama su argumentais ir įvertinama, kai iškviečiama lambda funkcija:

```none
lambda argument: expression
```

Funkcijos yra pagrindinė beveik kiekvienos programavimo kalbos konstrukcija, jos yra mažiausias pakartotinai naudojamas kodo vienetas. Paprastai **Python kalboje funkcijos apibrėžiamos naudojant raktinį žodį `def`**. Pateiksime pavyzdį – kvadratinę funkciją, kuri daugina skaičių iš jo paties:

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

`def` raktinis žodis yra gerai žinomas būdas apibrėžti funkcijas Python kalboje, tačiau šioje kalboje taip pat yra lambda funkcijos. Tai yra **anoniminės funkcijos, kurios apibrėžia išraišką su parametrais**. Lambda funkcijos gali būti naudojamos visur, kur tikimasi funkcijos arba kur ji gali būti priskirta vardui. Čia galite pamatyti lambda išraišką, lygią kvadrato funkcijai:

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

Note Python kalboje lambda funkcija reiškia funkciją, sukurtą naudojant raktinį žodį `lambda`. Lambda nėra konkrečios funkcijos pavadinimas, taip pat nėra vienas iš Python operatorių.

### Koks yra skirtumas tarp lambda ir def?

Gali atrodyti keista, kad Python leidžia kurti funkcijas tiek su `lambda`, tiek su `def`. Tačiau `Lambda` **nėra jo savybė**, o tik dar vienas būdas kurti trumpas funkcijas lokaliai. Kiekviena funkcija, sukurta su `lambda`, taip pat gali būti sukurta su `def`. Tačiau atvirkščiai tai nėra tiesa.

Sintaksės lygiu `lambda` ir `def` yra raktiniai žodžiai. Vienas pagrindinis skirtumas tarp jų yra Python **griežtas teiginių ir išraiškų atskyrimas**. Teiginiai yra kodo vykdymo žingsniai, o išraiškos yra įvertinamos kaip vertė.

`Def` pradeda teiginį, tiksliau sudėtinį **teiginį, kuris apima kitus teiginius**. `def` teiginyje gali būti tik `return` teiginiai. `return` teiginys grąžina reikšmę, kai iškviečiama funkcija, apibrėžta `def`.

Skirtingai nei `def` teiginys, **`lambda` pradeda išraišką, kurioje negali būti jokių teiginių**. Lambda išraiška priima vieną ar daugiau argumentų ir grąžina anoniminę funkciją. Kai lambda funkcija yra iškviečiama, joje esanti išraiška yra įvertinama su perduotais argumentais ir grąžinama.

### Kokie yra Python lambda išraiškų apribojimai?

Python sąmoningai apribojo lambda funkcijų naudingumą, nes paprastai **geriau** yra **pavadinti funkcijas**. Tai verčia programuotojus galvoti apie funkcijos reikšmę ir aiškiai atskirti jos dalis.

Lambda **funkcijos** negali turėti instrukcijų, skirtingai nei funkcijos, apibrėžtos raktiniu žodžiu `def`, kūnas. Todėl **lambda funkcijoje negalima naudoti `if`, `for` ir pan.** Taip pat negalima sukelti išimties, nes tam reikalingas `raise` teiginys.

Python kalbos lambda funkcijos gali turėti vieną išraišką, kuri įvertinama ją iškvietus. Lambda išraiškoje **negalima naudoti tipo anotacijų**. Šiandien dauguma Python kalbos lambda funkcijų naudojimo atvejų naudoja kitas technikas, pavyzdžiui, supratimus.

## Įvairūs lambda funkcijų naudojimo būdai Python kalboje

Lambda **išvestos iš funkcinio programavimo**. Kai kuriose kalbose, pavyzdžiui, JavaScript, anoniminės funkcijos plačiai naudojamos be specialaus raktažodžio. Python kalboje lambda išraiškos naudojamos nedidelėms funkcijoms kurti lokaliai. Toliau apžvelgsime jų naudingiausius pritaikymus.

### Kaip užpildyti aukštesnės eilės funkcijas Python kalboje naudojant lambda išraiškas

Lambdos dažnai naudojamos su **aukštesnės eilės funkcijomis, pvz., `map()`, `filter()` ir `reduce()`**. Dėl lambdų iteruojamo elemento elementai gali būti transformuojami be ciklų. Aukštesnės eilės funkcijos yra funkcijos, kurios kaip parametrus naudoja funkcijas arba grąžina funkciją.

Funkcija `map()` priima funkciją ir iteruojamąjį kaip parametrus. Ji vykdo funkciją kiekvienam iteruojamojo elementui. Pabandykime sugeneruoti kvadratinius skaičius. Naudojame funkciją `map()` ir **perduodame lambda išraišką kaip argumentą**, kuris sugeneruoja kvadratinę funkciją. Kvadratinė funkcija taikoma kiekvienam sąrašo elementui su `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 Nuo Python 3.0 versijos `map()` ir `filter()` funkcijos grąžina iteruojamą objektą, o ne sąrašą. `list()` iškvietimas naudojamas `assert` teiginiuose, kad išpakuotų iteruojamus objektus į sąrašą.

Sąrašų supratimas siūlo **modernesnį požiūrį į iteruojamų elementų apdorojimą**. Vietoj to, kad naudotume `map()` ir generuotume lambda funkciją, galime tiesiogiai apibūdinti operaciją:

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

Funkcija `filter()` gali būti naudojama **iteruojamo elemento elementams filtruoti**. Mes galime išplėsti mūsų pavyzdį, kad būtų generuojami tik lyginiai kvadratiniai skaičiai:

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

Pateikiame pageidaujamą metodą, kai naudojamas sąrašo supratimas, kad **būtų gautas tas pats rezultatas nenaudojant lambda ir aukštesnės eilės funkcijų**. `if` supratimo dalis naudojama, kad būtų atrinkti lyginiai skaičiai iš generuotų kvadratinių skaičių:

```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 Python `reduce()` funkcija nuo Python 3.0 versijos nėra įtraukta į standartinę biblioteką. Ši funkcija yra `functools` modulyje.

### Kaip įgyvendinti pagrindines funkcijas Python kalboje naudojant lambda funkcijas

Supratimas iš esmės pakeitė klasikinės aukštesnės eilės funkcijas `map()` ir `filter()` Python kalboje. Tačiau **pagrindinės funkcijos gali būti naudojamos norint parodyti visus lambda funkcijų privalumus**.

Python palyginimo funkcijos `sorted()`, `min()` ir `max()` veikia iteruojamuose objektuose. Kiekvienas iteruojamo objekto elementas yra palyginamas, kai funkcija yra iškviečiama. Šios trys funkcijos priima raktinę funkciją kaip neprivalomą parametrą `key`. Raktinė funkcija yra iškviečiama kiekvienam elementui ir grąžina raktinę vertę palyginimo operacijai.

Apsvarstykime šią problemą. Turime aplanką su vaizdo failais, kurių pavadinimai yra susieti su Python sąrašu. Norime **surūšiuoti sąrašą**. Visi failų pavadinimai prasideda skaičiumi `img`, po kurio eina kitas skaičius:

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

Jei naudojame Python `sorted()` funkciją, **taikoma leksikografinė tvarka**. Ji traktuoja iš eilės einančius skaitmenis kaip vieną skaičių. Taigi skaičiai `['1', '2', '100']` yra išdėstomi tvarka `['1', '100', '2']`. Rezultatas nėra toks, kokio tikimės:

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

Mes **perduodame `lambda` išraišką, kuri sukuria raktinę funkciją**, kad užtikrintume teisingą rūšiavimą. Raktinė funkcija išskiria failo vardo skaitmeninę dalį, kuri naudojama kaip raktas `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']
```

Pagrindinė funkcija naudojama lokaliai ir tik vieną kartą. Nėra būtina apibrėžti papildomos pavadintos funkcijos. **Lambdos yra teisingas būdas kurti pagrindines funkcijas**. Pažvelkime į dar du pavyzdžius.

Kaip ir `sorted()`, įdiegtos Python funkcijos `min()` ir `max()` naudoja pasirinktinę raktų funkciją. Šios funkcijos suranda mažiausią ir didžiausią elementą sąraše ar kitame kartotiniame objekte. **Mažiausias ar didžiausias elementas yra apibrėžimo klausimas** ir gali būti nurodytas naudojant raktų funkciją.

Aišku, ką reiškia mažiausias arba didžiausias elementas paprastų verčių sąrašuose, pavyzdžiui, skaičių sąraše. Šiuo atveju specialios raktinės funkcijos nereikia:

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

Note Jei raktinė funkcija neperduodama, kaip numatytoji naudojama tapatybės funkcija `f(x) = x`. Tai galima lengvai apibrėžti kaip Python lambda su `lambda x: x`.

Bet kas, jei kiekvienas iteruojamo elemento elementas apima kelias datas? Įsivaizduokime sąrašą, kuriame yra žmonių vardai ir amžius. Kokie yra **kriterijai, pagal kuriuos** sprendžiama, kuris **iš `min()` ir `max()`** yra mažiausias ir didžiausias elementas? Čia praverčia raktinė funkcija.

Mums reikia **pavyzdinių duomenų**, kad galėtume iliustruoti, kaip veikia pagrindinės funkcijos. Sukurkime funkciją `Person()`, kuri veiks kaip konstruktorius:

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

Mes **sukuriame žmonių sąrašą** naudodami mūsų konstruktoriaus funkciją:

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

Rasti vyriausią asmenį naudojant `max()` skambutį. Tai **sukuria raktinę funkciją** naudojant lambda išraišką, kuri paima asmens žodyną ir iš jo išskiria amžių kaip palyginimo elementą:

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

Šis metodas veikia lygiai taip pat ir `min()` funkcijai. Šiuo atveju **apibrėšime pagrindinę funkciją už `min()` iškvietimo ribų** ir vėl panaudosime lambda išraišką. Tai pagerina skaitomumą ir yra naudinga, jei pagrindinė funkcija turi kelis vietinius naudojimus:

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

### Kaip sukurti uždarymus naudojant Python lambda funkcijas

Python lambda taip pat naudojamos apibrėžiant uždarymus. Tai yra funkcijos, kurias sukuria kitos funkcijos ir kurios saugo vertę. Uždarymai gali būti **naudojami** panašių funkcijų **šeimoms kurti**. Pateiksime dažną pavyzdį, kai kuriamos galios funkcijos.

Eksponentinės funkcijos priima argumentą ir pakelia jį laipsniu. Gerai žinomi pavyzdžiai yra kvadratinė funkcija `f(x) = x ^ 2` ir kubinė funkcija `f(x) = x ^ 3`. Bet kokios eksponentinės funkcijos gali būti generuojamos kaip uždarymai naudojant konstruktoriaus funkciją. Naudosime lambda išraišką, o tai reiškia, kad mums nereikės apibrėžti vidinės pavadintos funkcijos:

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

### Kaip naudoti iškart iškviečiamą funkcijos išraišką (IIFE) su Python lambda funkcijomis

IIFE, tariama „iffy“, yra **žinomas JavaScript modelis**. Jis apima anoniminės funkcijos apibrėžimą ir jos nedelsiamą vykdymą.

**Lambdas gali būti naudojamos kaip IIFE**, nors dėl Python apribojimų jos nėra labai naudingos. Mums reikia tik įdėti skliaustelius aplink lambda išraišką:

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

Ir dar viena pora skliaustų, kuriuose yra argumentas (-ai):

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

Tip Python pradedantiesiems rekomenduojame peržiūrėti mūsų Python pamoką.


This is a markdown version of: [https://www.ionos.com/lt-lt/digitalguide/interneto-svetaines/interneto-svetainiu-kurimas/lambda-funkcijos-python-kalboje/](https://www.ionos.com/lt-lt/digitalguide/interneto-svetaines/interneto-svetainiu-kurimas/lambda-funkcijos-python-kalboje/) for AI/LLM consumption.