在python中使用递归来反转列表

时间:2015-12-15 16:57:36

标签: python list python-2.7 python-3.x recursion

def revlist(lst):
    if len(lst) == 1:
        return lst
    else:
        return lst[(len(lst) - 1)

我已经到了这一点,但我不知道接下来该做什么。我正在为我的考试练习递归。如果有人能提供帮助,我将不胜感激。

5 个答案:

答案 0 :(得分:7)

您的简单情况很好,如果列表的长度为1(或更小),只需返回列表即可。实际上,我们可以简单地检查列表是否为空(通过发出if not 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]

答案 1 :(得分:5)

另一种方式

def revlist(lst):
    if len(lst) == 0:
        return ([])
    else:
        return (revlist(lst[1:]) + [lst[0]] )

答案 2 :(得分:3)

使用 fold

的想法编写的版本

我们需要一个我们称之为缺点的函数(这来自lisp / scheme等)。它需要一个元素和一个列表,并将该元素添加到列表的头部(开始)。请注意,在python中这不是很有效。

def cons(x,xs):
  return [x] + xs

现在功能折叠(严格来说是左折)。这是一个功能本身,可以用于很多的东西(参见链接)python等价物可能是reduce。请注意,它需要一个函数f并将此函数应用于列表的头部和变量acc(累加器的简称)

def foldl(f,acc,xs):
  if not xs:         
    return acc
  head, *tail = xs
  return foldl(f, f(head,acc), tail)

现在我们可以编写一个递归的反向版本(因为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)

如果我们要定义一个正确的折叠,如下所示:

def foldr(f,acc,xs):
  if not xs:         
    return acc
  head, *tail = xs
  return f(head, foldr(f, acc, tail))

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

答案 3 :(得分:2)

想想你为每次递归调用想要实现的目标。 thefourtheye在他的评论中提到的链接显示了如何使用递归对列表求和的真实例证:

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([])))))

然后更简洁地显示您想要实现的目标。最后,这就是你得到的。

def revlist(lst):
    if not lst:
        return []
    else:
        return lst[-1:] + revlist(lst[:-1])

答案 4 :(得分:0)

基本情况是你没有列表,所以你想要返回空列表。

你是这样做的递归情况,所以你想在列表的其余部分前面添加最后一个元素到递归调用。

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))

这返回:

12:03 $ python test.py 
[5, 4, 3, 2, 1]

这适用于所有迭代。