#python #recursion
Вопрос:
import sys
sys.setrecursionlimit(15000)
import time
def factorialHead(n):
if n <= 1:
return 1
else:
return n * factorialHead(n - 1)
print("Head Recursion:")
now = time.time()
factorialHead(10000) # this should break as I understand - stackoverflow (seems to work fine??)
print(time.time() - now)
def factorialTail(n, currentValue = 1):
if n <= 1:
return currentValue
else:
return factorialTail(n-1, n*currentValue)
print("Tail Recursion:")
now = time.time()
factorialTail(10000)
print(time.time() - now)
# Output:
# Head Recursion:
# 0.02311873435974121
# Tail Recursion:
# 0.05035591125488281
#Switched Order
# Tail Recursion:
# 0.05422401428222656
# Head Recursion:
# 0.017311573028564453
Несколько новичок в python и кодировании в целом. Играл с некоторыми рекурсивными функциями головы и хвоста и заметил некоторое странное поведение в рекурсивной функции головы. Это своего рода «воссоздание» того, с чем я столкнулся. Насколько я понимаю стек, приведенная выше рекурсия head должна выдавать ошибку stackoverflow. Он не только не делает этого, но, похоже, работает лучше, чем хвостовой рекурсивный эквивалент.
Может кто-нибудь, пожалуйста, объяснить, что здесь происходит, что я упускаю?
Python=3.8.10 (только для справки)
Комментарии:
1. ну, для начала, вы должны знать, что в Python нет оптимизации хвостовых вызовов, поэтому и то, и другое должно вызывать ошибку рекурсии на одинаковой глубине.
2. В любом случае, вы установили максимальный предел рекурсии
15000
, почему вы ожидаете , что он нарушится10000
??? Обратите внимание, что и то, и другое ломается, если вы используетеheadRec(15000)
иtailRec(15000)
вызываете ожидаемую ошибку3. Прежде всего, одного эксперимента недостаточно. Во-вторых, вы должны использовать
timeit
, а не одноразовуюtime.time
ссылку, чтобы уменьшить шум в ваших наблюдениях. В-третьих, поскольку Python обычно не оптимизирует хвостовые вызовы, вы пытаетесь измерить то, чего нет в вашей системе времени выполнения. Далее, как сказал Хуан, сначала вы не достигли указанного вами предела стека, поэтому совсем не ясно, почему вы ожидаете, что ваша программа будет выдавать и исключать.4. Для иллюстрации того, как реализовать правильную хвостовую рекурсию в Python, см. Этот блог .
5. Наконец, поскольку обе функции повторяются на одной и той же глубине, почему вы думаете, что именно одна из них должна ошибаться? Вы хотите, чтобы рекурсия была сведена к циклу?