我对python有点菜鸟,但我正在尝试创建一个递归函数,它就像内置的范围函数一样工作:
def Range (lo, hi):
if lo >= hi:
return []
else:
return [lo, Range (lo+1,hi)]
但它返回多个列表。
而不是[3,4,5,6]
,这是我想要的,它返回[3,[4,[5,[6,[]]]]]
为什么会这样,我该如何解决?
当你这样递归时,Range
每次返回一个列表:
Range(3,7)
# translates to
[3, Range(4,7)]
# which translates to
[3, [4, Range(5,7)]]
# etc.
为了避免这种情况,请将您的列表添加在一起:
def Range (lo, hi):
if lo >= hi:
return []
else:
return [lo] + Range(lo+1, hi)
编辑:
正如@delnan 指出的那样,这个函数非常低效——它都在没有尾调用优化的语言中递归* 并且它为每个递归级别生成两个(可能三个)新列表。@mipadi 的答案更高效,因为它只创建一个列表(acc
或accumulator
参数)并在递归时传递它。
* 这对于 Python 语言可能不是真的,但我 99% 确信它对于最常见的 Python 实现(即 CPython)是正确的。
您的Range
函数返回一个列表,因此在最后一行中,您将返回一个列表中的列表。您可能应该做的是维护一个累加器并为其添加值:
def Range(lo, hi, acc=None):
if acc is None:
acc = []
if lo >= hi:
return acc
else:
acc.append(lo)
return Range(lo+1, hi, acc)
def Range (lo, hi):
if lo >= hi:
return []
else:
return [lo] + Range (lo+1, hi)
但你可能会得到 StackOverflow
每次递归到 Range 都会返回一个列表,该列表是上一次递归的列表中的第二个元素。当然Python 对此有一个内置函数,但如果你想自己构建它,你可能只想以
return [lo] + Range(lo+1, hi)