几天前有人对我说,递归比迭代更好,如果可能的话,应该始终使用。
因此,我开始研究递归并尝试编写一个简单的程序来获取数字的阶乘。这是递归:
def fact(n):
if n == 1:
return 1
return n * fact(n - 1)
虽然这工作正常,但它得到一个 RuntimeError: maximum recursion depth exceeded
尽快n
超过 997。
所以我写了一个简单的函数,它的功能完全相同,但带有 for loop
.
def fact(n):
a = 1
for x in range (0, n, 1):
a = a * (n - x)
return a
同时 n < 10000
它在 150 毫秒内给出答案。
所以,我虽然也许递归在数量少的情况下会更快,但不是。需要更长的时间:
所以我的问题是:
在用 Python 编写程序时是否有任何理由使用递归?
和:
有没有只能用递归解决的问题?
没有需要显式递归解决的问题;并且没有需要通过显式迭代解决的问题 - Church and Turing have proved它们是可以互换的。
然而,有些问题的代码更简洁,如果您使用递归,则更容易推理。事实上,Python 标准库甚至 C 代码本身在许多地方都在内部使用递归,因此很容易在许多地方达到可怕的递归限制,例如打印嵌套元组的 repr
:
>>> from functools import reduce
>>> x = reduce(lambda x, y: (x,), range(10000))
>>> x # recursion limit hit in C code
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: maximum recursion depth exceeded while getting the repr of a tuple
>>> import pprint
>>> pprint.pprint(x) # recursion limit hit in Python standard library code.
Traceback (most recent call last):
...
File "/usr/lib/python3.4/pprint.py", line 390, in _safe_repr
orepr, oreadable, orecur = _safe_repr(o, context, maxlevels, level)
File "/usr/lib/python3.4/pprint.py", line 340, in _safe_repr
if issubclass(typ, dict) and r is dict.__repr__:
RuntimeError: maximum recursion depth exceeded while calling a Python object
您始终可以使用状态机和中间参数堆栈将递归算法转换为迭代,因为毕竟这正是 CPU 实现递归所做的工作。