Rekurze (angl. recursion) je programátorská technika, kdy funkce volá sebe sama.
Jednoduchá rekurze skončí nekonečným voláním. Zkus zadat tento program:
def rekurzivni_funkce():
vysledek = ...
rekurzivni_funkce()
return vysledek
rekurzivni_funkce()
Jak to funguje?
rekurzivni_funkcerekurzivni_funkce:rekurzivni_funkce:rekurzivni_funkce:rekurzivni_funkce:rekurzivni_funkce:Tomu odpovídá chybová hláška:
Traceback (most recent call last):
File "/tmp/ukazka.py", line 4, in <module>
rekurzivni_funkce()
File "/tmp/ukazka.py", line 2, in rekurzivni_funkce
return rekurzivni_funkce()
File "/tmp/ukazka.py", line 2, in rekurzivni_funkce
return rekurzivni_funkce()
File "/tmp/ukazka.py", line 2, in rekurzivni_funkce
return rekurzivni_funkce()
[Previous line repeated 996 more times]
RecursionError: maximum recursion depth exceededHláška je zkrácená – dva řádky by se správně měly opakovat 999×, ale novější verze Pythonu je vypíšou jen třikrát.
Jak rekurzi využít v praxi? Jeden způsob je si počítat, kolikrát se ještě „zanořit“.
Představ si potápěče, který prozkoumává mořské hlubiny následujícím způsobem:
Neboli v Pythonu:
def pruzkum(hloubka):
print(f'Rozhlížím se v hloubce {hloubka} m')
if hloubka >= 30:
print('Už toho bylo dost!')
else:
print(f'Zanořuju se (z {hloubka} m)')
pruzkum(hloubka + 10)
print(f'Vynořuju se (na {hloubka} m)')
pruzkum(0)
pruzkumpruzkum s hloubkou 0:Rozhlížím se v hloubce 0 m0 ≥ 30 (což neplatí)Zanořuju se (z 0 m)pruzkum s hloubkou 10 m:Rozhlížím se v hloubce 10 m10 ≥ 30 (což neplatí)Zanořuju se (z 10 m)pruzkum s hloubkou 20 m:Rozhlížím se v hloubce 20 m20 ≥ 30 (což neplatí)Zanořuju se (z 20 m)pruzkum s hloubkou 30 m:Rozhlížím se v hloubce 30 m30 ≥ 30 (což platí! konečně!)Už toho bylo dost!Vynořuju se (na 20 m)Vynořuju se (na 10 m)Vynořuju se (na 0 m)Na předchozím příkladu je vidět zajímavé chování lokálních proměnných. Když je potápěč „na dně“, jakou hodnotu má proměnná hloubka?
Tahle otázka je chyták. Která proměnná hloubka?
Když je program „na dně“, existují čtyři různé lokální proměnné hloubka:
každé zanoření, každé zavolání funkce pruzkum, má vlastní proměnnou.
Podobně jako když máš globální a lokální proměnnou stejného jména, každá funkce „vidí“ jen tu svoji proměnnou. Ale když se potápěč vynoří a volání funkce se ukončí, tato proměnná přestane existovat. A „volající“ funkce vidí svoji proměnnou, ve které je stále původní hodnota.
Nemáš-li ráda matematiku, tuhle sekci přeskoč!
Rekurzivní algoritmy mají původ v matematice. Faktoriál x, neboli součin všech čísel od 1 do x, zapsaný jako x!, matematici definují takto:
Neboli v Pythonu:
def factorial(x):
if x == 0:
return 1
elif x > 0:
return x * factorial(x - 1)
print(factorial(5))
print(1 * 2 * 3 * 4 * 5)