Syntaktický cukr
Zjednodušený cyklus (vytváření seznamů)
Uvažujte následující příklad inicializace seznamu:
>>> for x in range(10):
... squares.append(x**2)
...
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Nešlo by to nějak stručněji? Šlo:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Tento zkrácený zápis může být i vnoření cyklus a mít na konci podmínku if
.
Pokud není podmínka if
splněna, do výsledného seznamu (listu …) se
hodnota/výraz nedostane.
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
Další příklad transponuje matici (resp. seznam seznamů).
>>> [[row[i] for row in matrix] for i in range(4)]
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
Obdobně to jde i s typem set:
{'r', 'd'}
A nebo se slovníkem:
{2: 4, 4: 16, 6: 36}
A nebo s n-ticí:
<generator object <genexpr> at 0xb7303144>
A ejhle, ona se nevytvořila n-tice, ale jakýsi generátor.
Vzpomeňte si na funkci (x)range(),
která vracela typ 'range'. Zde to má význam stejný – šetří se
paměť počítače.
Vytvoření generátoru dává vcelku u neměnitelné n-tice
smysl (narozdíl od měnitelného seznamu).
Bacha na to, že do tohoto generátoru nelze přistupovat pomocí indexů. Pokud byste něco takového potřebovali, není nic snazšího než převést generátor na n-tici:
>>> n = list(g)
>>> n[4]
16
>>> g[4]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'generator' object is not subscriptable
Lambda funkce
Klíčové slovo lambda
se používá pro
vytvoření nepojmenovaných funkcí. Hodí se v případech, kde chcete
vytvořit funkci „na jedno použití“. Tedy tam, kde by
jste normálně definovali funkci (pomocí def
), pak ji
jednou použili a zase smazali.
Tělo lambda funkce je omezené na jeden výraz. Takže jako lambda funkce není možné psát nic extra složitého.
Za klíčové slovo lambda
se píší jména argumentů (nejsou
v závorce), pak dvojtečka a pak výraz, který je zároveň tělem i návratovou
hodnotou lambda funkce.
<function <lambda> at 0xb72fd8b4>
>>> def inc(x):
... return x + 1
...
>>> inc(5)
6
>>> inc = lambda x: x + 1
>>> inc(5)
6
Funkce vytvořené uvnitř jiné funkce mají přístup k lokálním proměnným funkce, která je vytváří. Toho se dá využít. Pokud funkci vrátíte jako návratovou hodnotu, lokální proměnné vytvářející funkce budou stále s vytvořenou funkcí svázány (funguje to podobně jako v JavaScriptu, jestli to znáte).
... return lambda *hodnoty: "{}{}{}".format(start, " ".join(hodnoty), end)
...
>>> u = uzavorkovavac('{', '}')
>>> u('a', 'b', 'c')
'{a b c}'
>>> h1 = uzavorkovavac('<h1>', '</h1>') # nove volani fce uzavorkovavac() -> nove lokalni promenne
>>> h1('zdar')
'<h1>zdar</h1>'
>>> u('zdar') # porad pristupuje k puvodnim lokalnim promennym start a end
'{zdar}'
>>>
Zdůrazňuji, že tato vlastnost s uchováváním odkazů na lokální proměnné
nadřazené funkce se netýkají jen lambda funkcí, ale i funkcí definovaných
pomocí def
(definovaných uvnitř jiné funkce).
Použití lambda
je opravdu jen syntaktický cukr.