„Skutečný“ funkcionální jazyk nemá žádné proměnné – jednou přiřazené hodnoty jsou takovými už navždy. Podobně chování funkcí je zcela určeno pouze jejich vstupními parametry a navíc funkce nemění své okolí.
Python nesplňuje žádnou z těchto podmínek. Dokonce byste asi měli docela problém napsat program bez použití proměnných. Ale svým protežováním iterovatelných sekvenčních typů se pojetí funkcionálních jazyků docela blíží. Dokonce pro práci s nimi nabízí kromě generátorové notace i několik speciálních funkcí.
V dalším se podíváme na několik základních (nejen čistě) funkcionálních prvků jazyka Python.
Generátorová notace patří mezi jednu z nejtypičtějších pythoních konstrukcí. Umožňuje velmi snadno na místě jednoho řádku za pomoci členů sekvence vyrábět sekvence (seznamy, množiny a slovníky) jiné.
Pro seznam má v principu dvě následující podoby (přičemž PRVEK je nejčastěji nějakou funkcí prvků procházené SEKVENCE):
K typicky funkcionálním operacím patří operace prováděné nad celou sekvenční strukturou najednou.
Přitom platí, že je-li možné výsledek operace určit dříve, než je prozkoumána sekvence celá, také se tak stane (takže se nepočítají zbytečné kroky).
Funkce any(ITERABLE)
vrací True
, je-li alespoň jeden prvek z iterovatelné struktury vyhodnocen jako pravdivý. Pro prázdnou strukturu vrací False
:
Funkce all(ITERABLE)
vrací True
, jsou-li všechny prvky z iterovatelné struktury vyhodnoceny jako pravdivé. Pro prázdnou strukturu vrací také True
:
Funkce min(SEKVENCE)
vrací nejmenší prvek ze sekvence:
Funkce max(SEKVENCE)
vrací největší prvek ze sekvence:
Funkce sum(SEKVENCE)
vrací součet prvků v sekvenci:
Funkce map(FUNKCE, ITERABLE)
vrací iterátor, který postupně mapuje funkci na jednotlivé prvky iterovatelné struktury:
Často je jednodušší a průhlednější napsat příslušný generátorový výraz [f(x) for x in xs].
Funkce filter(FUNKCE, ITERABLE)
vrací iterátor, který postupně vrací ty prvky iterovatelné struktury, pro něž zadaná funkce poskytuje True
:
Pro funkci různou od None
je často je jednodušší a průhlednější napsat příslušný generátorový výraz [x for x in xs if f(x)].
Asi už nepřekvapí, že:
Funkce zip(*ITERABLES)
vrací iterátor, který skládá dohromady do n-tic navzájem si odpovídající prvky z jednotlivých vstupních iterovatelných struktur:
Přitom platí:
itertools.zip_longest()
.
Další funkcionální prostředky obzvláště pro práci s funkcemi (higher-order functions) poskytuje modul functools. Podívejme se na (velmi omezený) výběr z nich:
Funkce reduce(FUNKCE, ITERABLE[, VýchozíHodnota])
destruktivně aplikuje zadanou binární funkci postupně na dvojce prvků z iterovatelné struktury a vrací výsledek. Příklad je názornější:
Funkce partial(func, *args, **keywords)
vrací novou funkci (resp. callable), kterou vyrobí ze zadané tak, že některé její argumenty „zafixuje“ předanými hodnotami. Příklad bude opět názornější:
V modulu functools
je toho k dispozici mnohem více, ale použití ostatních – byť velmi zajímavých! (např. single-dispatch generic functions) – nástrojů je většinou již značně „zamotané“. S trochou času a štěstí na tento modul někdy napíšu samostatnou přednášku
Lambda-funkce jsou anonymní (tj. bezejmenné) funkce definované typicky v rámci jednoho řádku a skládající se pouze z jednoho výrazu, který je vyhodnocován ve chvíli volání funkce:
Pythonovské lambda-funkce jsou v porovnání s prakticky libovolnou jinou implementací velmi omezené – mohou obsahovat pouze jeden výraz, a to ještě bez složitějších, natožpak dokonce víceřádkových konstrukcí.
Ve většině případů ale zastanou obdobnou práci „obyčejné“ funkce v Python'u, protože jsou tzv. first-class object/citizen. (Což především znamená, že je možné je předávat jako parametry do jiných funkcí, vracet je jako návratové hodnoty z funkcí a ukládat je v datových strukturách.)
Naprosto typickým prvkem funkcionálního programování je vytváření (potenciálně i nekonečných) struktur, z nichž se vrací pouze ta část, která je aktuálně vyžadována, a nic dalšího se (zatím) nepočítá.
V Python'u se konstruktorům takových objektů říká generátory a jelikož jsou velmi důležité, je jim věnována samostatná přednáška.