-
Recursividad en Python
🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍
/JavierLuna
@javierlunamolina
/in/jlunamolina/
+
🐍🐍🐍🐍🐍🐍🐍🐍🐍
=
❤️
"para entender la recursividad primero hay que entender la recursividad"
Factorial!
📂 /jluna
📄 EnLaPlaya.png.exe
📂 /Downloads
📂 /home
📄 illo.txt
📂 /jluna
📂 /Downloads
🐍 ejemplo.py
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4]
[3, 4]
Nop, pero 4 < 5
Nop, pero 4 > 2
Oh yeah!!
def factorial(n):
if n in {0, 1}:
return 1
return n * factorial(n-1) <---
def fib(n):
if n in {0, 1}:
return n
return fib(n-1) + fib(n-2) <-- 2x
###
def a():
b() <---
def b():
a() <---
###
def f(callable):
callable() <---
...
def f9996():
return f9995()
def f9997():
return f9996()
def f9998():
return f9997()
def f9999():
return f9998()
f9999()
😭
File "recursive.py", line 18004, in f9001
return f9000()
RecursionError: maximum recursion depth exceeded
f_a(1,2)
f_b()
f_c(42)
f_d("hello!")
push(element)
pop() -> element
__main__()
def fun_a():
return "Hello!"
def fun_b():
return fun_a()
fun_b() <---
__main__() -> fun_b()
__main__
def fun_a():
return "Hello!"
def fun_b(): <---
return fun_a() <---
fun_b()
__main__()
└──fun_b() -> fun_a()
fun_b()
__main__
def fun_a(): <---
return "Hello!" <---
def fun_b():
return fun_a()
fun_b()
__main__()
└──fun_b()
└── fun_a() -> "Hello!"
fun_b()
fun_a()
__main__
def fun_a():
return "Hello!"
def fun_b():
return fun_a() <--- "Hello!"
fun_b()
__main__()
└──fun_b() -> "Hello!"
fun_b()
__main__
def fun_a():
return "Hello!"
def fun_b():
return fun_a()
fun_b() <--- "Hello!"
__main__() -> "Hello!"
def f_a(arg1, arg2):
local_var = 3
return f_b(3, 4)
Loaded variables:
arg1, arg2, local_var, f_b
Code itself
Bookeeping:
nombre archivo, número de fila, ref a frames anteriores..
function(3, 4)
import inspect
stack = inspect.stack()
current_frame = stack[0]
loaded_vars = current_frame.frame.f_locals
print(loaded_vars)
f_a(1,2)
f_b()
f_c(42)
f_d("hello!")
Límite "logico"
Límite "logico"
Límite "físico"
El valor del límite lógico depende del sistema, pero suele estar capado a 1000
f_a(1,2)
f_b()
f_c(42)
f_d("hello!")
El valor del límite lógico depende del sistema, pero suele estar capado a 1000
import sys
sys.getrecursionlimit() -> 1000
sys.setrecursionlimit(100_000_000)
f_a(1,2)
f_b()
f_c(42)
f_d("hello!")
Límite "logico"
Límite "logico"
Límite "físico"
f_d("hello!")
(o...no *llora lenta pero recursivamente*)
Una llamada a una subrutina está "en la cola" si está situada en el último lugar de un procedimiento
def f():
return a()
def f2(n):
if n == 1:
return a()
else:
return b()
def f():
result = a()
print(result)
return result
def f2(n):
return a() + 1
✅
❌
f_a(1,2)
f_b()
f_c(42)
f_d("hello!")
a()
└─b() -> c()
a()
b()
a()
└─ c()
a()
c()
a()
a() "wtf pero si yo había llamado a b()"
😀
Traceback (most recent call last):
File "illooo.py", line 10, in <module>
c()
File "illooo.py", line 8, in c
b()
File "illooo.py", line 5, in b
a()
File "illooo.py", line 2, in a
raise Exception("Obscure exception")
Exception: Obscure exception
Traceback (most recent call last):
File "illooo.py", line 5, in <module>
a()
File "illooo.py", line 2, in a
raise Exception("Obscure exception")
Exception: Obscure exception
Con TCO
Sin TCO
def fib(n):
if n in {0, 1}:
return n
return fib(n-1) + fib(n-2)
def fib(n):
if n in {0, 1}:
return n
for _ in range(n):
a, b = b, a + b
return a
🧑🔬👩🔬
🐍
🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍🐍
🐍