编辑:我在 python 中回答这个问题,因为虽然它当前标记为 language-agnostic,但 python 是一个很好的、可执行的伪伪代码。
如果您可以以 尾递归 的形式编写函数,即以类似于def f(x): return f(g(x)) 的形式,则很容易将其转换为迭代形式。不幸的是,您通常不会得到尾递归调用,因此您需要了解一些技巧。
首先,假设我们有一个如下所示的函数:
def my_map(func, my_list):
if not my_list:
return []
return [func(my_list[0])] + change_my_list(my_list[1:])
好的,所以它是递归的,但不是尾递归:它真的是
def my_map(func, my_list):
if not my_list:
return []
result = [func(my_list[0])] + change_my_list(my_list[1:])
return result
相反,我们需要稍微调整函数,添加传统上所谓的累加器:
def my_map(func, my_list, acc = [])
if not my_list: return acc
acc = acc + func(my_list[0])
return my_map(func, my_list[1:], acc + func(my_list[0]))
现在,我们有了一个真正的尾递归函数:我们已经从 def f(x): return g(f(x)) 变为 def f(x): return f(g(x))
现在,将该函数转换为非递归形式非常简单:
def my_map(func, my_list, acc=[]):
while True: #added
if not my_list: return acc
#return my_map(func, my_list[1:], acc + func(my_list[0])) #deleted
func, my_list, acc = func, my_list[1:], acc + func(my_list[0]) #added
现在,我们稍微整理一下:
def my_map(func, my_list):
acc = []
while my_list:
acc.append(func(my_list[0])
my_list = my_list[1:]
return acc
请注意,您可以使用 for 循环或列表推导进一步清理它,但这留给读者作为练习。
好的,这是一个病态的例子,希望你知道python有一个内置的map函数,但过程是一样的:转换成尾递归形式,用参数重新分配替换递归调用,然后收拾一下。
所以,如果你有:
def make_products(list_of_lists):
if not list_of_lists: return []
first_list = list_of_lists[0]
rest = list_of_lists[1:]
return product_of(first_list, make_products(rest))
您可以将其转换为尾递归形式
def make_products(list_of_lists, acc=[]):
if not list_of_lists: return acc
first_list = list_of_lists[0]
rest = list_of_lists[1:]
acc = product_of(acc, first_list)
return make_products(rest, acc)
那么,这简化为:
def make_products(list_of_lists):
acc=[]
while list_of_lists:
first_list = list_of_lists[0]
rest = list_of_lists[1:]
acc = product_of(acc, first_list)
list_of_lists = rest
return acc
同样,这可以进一步清理,进入for 循环:
def make_products(list_of_lists):
acc=[]
for lst in list_of_lists:
acc = product_of(acc, lst)
return acc
如果您查看过内置函数,您可能会注意到这有点熟悉:它本质上是 reduce 函数:
def reduce(function, iterable, initializer):
acc = initializer
for x in iterable:
acc = function(acc, x)
return acc
所以,最终的形式是这样的
def make_products(list_of_lists):
return reduce(product_of, list_of_lists, []) # the last argument is actually optional here
然后您只需要担心编写product_of 函数。