programowanieProgramista Python

Opowiedz o funkcjach lambda w Pythonie. Jakie są ich ograniczenia w porównaniu do zwykłych funkcji? W jakich sytuacjach preferuje się ich stosowanie, a w jakich — należy ich unikać?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź

Funkcja lambda to anonimowa (bezimienna) funkcja definiowana za pomocą słowa kluczowego lambda. Zwykle jest używana tam, gdzie potrzebna jest krótka funkcja "jednorazowo i na miejscu".

add = lambda x, y: x + y print(add(1, 2)) # 3

Ograniczenia funkcji lambda:

  • Lambda może zawierać tylko jeden wyraz — jest to wartość zwracana, nie można używać wieloliniowych obliczeń, return, warunków typu if-else (tylko w postaci wyrażenia ternarnego).
  • Nie można używać złożonego kodu z try/except, pętli itd.
  • Lambda nie ma pełnej dokumentacji (nie można dodać docstring).
  • Funkcje lambda są gorzej czytelne, zwłaszcza gdy są zagnieżdżone.

Kiedy lambda jest przydatna:

  • W jednolinijkowych kluczach sortujących/filterujących (argumenty key; na przykład w sorted, filter, map).
  • Kiedy nie jest konieczne ponowne użycie kodu — operacje lokalne, szybko "podstawić funkcję".

Kiedy lepiej zrezygnować z lambdy:

  • W złożonej logice: dla ponownego użycia, z dużą ilością kodu lub warunków, dla zrozumiałości i czytelności lepiej wynieść do funkcji def z nazwą i dokstringiem.

Pytanie podchwytliwe

Pytanie: Czy funkcje lambda mogą używać zmiennych z kontekstu zewnętrznego i jak wpływa to na ich zachowanie podczas pracy wewnątrz pętli?

Odpowiedź: Funkcje lambda mogą przechwytywać zmienne z zewnętrznego kontekstu (zamknięcie leksykalne). Przy definiowaniu wewnątrz pętli często prowadzi to do nieoczekiwanego zachowania — lambda używa bieżącej wartości zmiennej w momencie wywołania, a nie tej, która "była w momencie definicji".

funcs = [] for i in range(3): funcs.append(lambda: i) # wszystkie funkcje zwrócą 2 (i=2 po pętli) print([f() for f in funcs]) # [2, 2, 2]

Aby przechwycić "stare" wartości:

funcs = [] for i in range(3): funcs.append(lambda i=i: i) print([f() for f in funcs]) # [0, 1, 2]

Przykłady rzeczywistych błędów spowodowanych brakiem znajomości szczegółów tematu


Historia

W projekcie używano lambdy do filtrowania listy słowników według określonego klucza. Lambda wewnątrz pętli przechwytywała zmienną, która w momencie wywołania miała inną (nieoczekiwaną) wartość. Efekt — błędne filtrowanie i błędy w raportach.


Historia

Duży projekt na Django: złożona forma walidacji, realizowana jako długie wyrażenie wewnątrz funkcji lambda. W późniejszym czasie logika biznesowa uległa zmianie, lambda przestała obejmować cały kod, trzeba było przepisać na zwykłą funkcję. Lambda spowolniła debugowanie.


Historia

W jednym startupie nieudolnie zastosowano lambdę do przekazywania funkcji sortującej, zapominając, że zwraca ona niepoprawny typ (na przykład, nie krotka, a lista). To prowadziło do nieprzewidywalnego sortowania i błędów z deduplikacją danych.