在python中使用递归反转列表

在python中使用递归反转列表,python,list,python-2.7,python-3.x,recursion,Python,List,Python 2.7,Python 3.x,Recursion,我已经走到了这一步,但我不知道下一步该怎么办。我在为考试练习递归。如果有人能帮助我,我将不胜感激。基本情况是您没有列表,所以您希望返回空列表 递归的情况就是这样,所以您希望在列表其余部分的递归调用前加上最后一个元素 def revlist(lst): if len(lst) == 1: return lst else: return lst[(len(lst) - 1) 这是我写的一个司机: def revlist(lst): if no

我已经走到了这一步,但我不知道下一步该怎么办。我在为考试练习递归。如果有人能帮助我,我将不胜感激。

基本情况是您没有列表,所以您希望返回空列表

递归的情况就是这样,所以您希望在列表其余部分的递归调用前加上最后一个元素

def revlist(lst):
    if len(lst) == 1:
        return lst
    else:
        return lst[(len(lst) - 1)
这是我写的一个司机:

def revlist(lst):
    if not lst:
        return lst
    # Create a list containing only the last element
    last = [lst[-1]]
    # Rest contains all elements up to the last element in `lst`
    rest = lst[:-1]
    # Prepend last to recursive call on `rest`
    return last + revlist(rest)
这返回:

lst = [1, 2, 3, 4, 5]
print(revlist(lst))

这将适用于所有iterables。

想想您试图为每个递归调用实现什么。thefourtheye在评论中提到的链接非常好地说明了如何使用递归求和列表:

12:03 $ python test.py 
[5, 4, 3, 2, 1]
以此为基点,如何实现反向列表?它可能看起来像:

listSum([1, 3, 4, 5, 6]) = 1 + listSum([3, 4, 5, 6])
                         = 1 + (3 + listSum([4, 5, 6]))
                         = 1 + (3 + (4 + listSum([5, 6])))
                         = 1 + (3 + (4 + (5 + listSum([6]))))
                         = 1 + (3 + (4 + (5 + (6 + listSum([])))))
这将更简洁地显示您想要实现的目标。最后,这就是你会得到的

revlist([1, 3, 4, 5, 6]) = [6] + revlist([1, 3, 4, 5])
                         = [6] + ([5] + revlist([1, 3, 4]))
                         = etc etc
                         = [6] + ([5] + ([4] + ([3] + ([1] + revlist([])))))

如果列表的长度为1(或更小),只需返回列表即可。事实上,我们可以简单地检查列表是否为空(通过发出
if not lst
)。如果列表较大,则必须考虑如何简化递归情况下的问题。 换句话说,你可以这样表述: 如果列表长度大于1,请给出该列表的最后一个元素,该元素由我在反转给定列表时得到的列表扩展,而列表中没有最后一个元素。后一个列表比原始列表小一个,因此简化了问题

代码:

def revlist(lst):
    if not lst:
        return []
    else:
        return lst[-1:] + revlist(lst[:-1])
另一种方式

def reverse(lst):
    if not lst: # this will be true if lst == []
        return lst
    return lst[-1:] + reverse(lst[:-1]) # recursive case

# Demo
print(reverse([1,2,3,4,5])) # [5, 4, 3, 2, 1]

使用

我们需要一个调用cons的函数(它来自lisp/scheme等)。它接受一个元素和一个列表,并将该元素添加到列表的开头(开始)。请注意,在python中,这是没有效率的

def revlist(lst):
    if len(lst) == 0:
        return ([])
    else:
        return (revlist(lst[1:]) + [lst[0]] )
现在函数折叠(严格地说是左折叠)。这本身就是一个函数,可以用于许多事情(参见链接),python的等价物可能是
reduce
。请注意,它采用函数
f
,并将此函数应用于列表标题和变量
acc
(累加器的缩写)

现在我们可以编写一个递归的reverse版本(因为fold是递归的)

因此,折叠体现了递归函数的思想。例如,如果我们想对一系列数字进行递归求和,我们可以将其定义为:

def reverse(xs):
  return foldl(cons, [], xs)
如果我们要定义一个右褶皱,如下所示:

from operator import add # this is just '+' as a function
def sum(xs):
  return foldl(add, 0, xs)

然后调用
foldr(cons,[],xs)
将返回与初始列表相同的列表

要理解递归的基础知识,可能会对您有所帮助。如果您没有递归(您从不在revlist中调用revlist),并且总是返回单个元素,那么您希望如何获得反向列表?你可能应该多学一点;)是的,我知道我应该这样做,但这也不完整,但我有点卡住了:(@thefourtheye阅读您的评论,我完全希望它以“您首先必须理解递归”结尾)逗号后。@erip和我都没有,但我已经得到了各地的幻影下票数,所以人们只需要把它吸起来,然后接受代表的意见。越简单,焦点越少。哦,不,去掉那些参数!对不起,lisp方式:DCute解。非常Lispy。+1不需要创建2个变量,调用堆栈就足够了。我明白这一点。我这样做是为了清晰,since OP似乎是个初学者。你说得对,回答清楚
def reverse(xs):
  return foldl(cons, [], xs)
from operator import add # this is just '+' as a function
def sum(xs):
  return foldl(add, 0, xs)
def foldr(f,acc,xs):
  if not xs:         
    return acc
  head, *tail = xs
  return f(head, foldr(f, acc, tail))