6

我想要一个函数,它将返回它给出的列表的反向 - 使用递归。我怎样才能做到这一点?

4

20 回答 20

14

将列表的第一个元素附加到反向子列表:

mylist = [1, 2, 3, 4, 5]
backwards = lambda l: (backwards (l[1:]) + l[:1] if l else []) 
print backwards (mylist)
于 2008-10-19T07:20:02.970 回答
11

更明确一点:

def rev(l):
    if len(l) == 0: return []
    return [l[-1]] + rev(l[:-1])

这变成:

def rev(l):
    if not l: return []
    return [l[-1]] + rev(l[:-1])

变成:

def rev(l):
    return [l[-1]] + rev(l[:-1]) if l else []

这与另一个答案相同。


尾递归/CPS 样式(python 无论如何都不会优化):

def rev(l, k):
    if len(l) == 0: return k([])
    def b(res):
        return k([l[-1]] + res)
    return rev(l[:-1],b)


>>> rev([1, 2, 3, 4, 5], lambda x: x)
[5, 4, 3, 2, 1]
于 2008-10-19T08:18:43.213 回答
7

我知道这不是一个有用的答案(尽管这个问题已经得到了回答),但是在任何真实的代码中,请不要这样做。Python 无法优化尾调用,函数调用速度慢并且递归深度固定,因此至少有 3 个原因可以改为迭代。

于 2008-10-19T08:50:19.483 回答
4

诀窍是在递归后加入:

向后定义(l):
  如果不是我:
    返回
  x, y = l[0], l[1:]
  向后返回(y) + [x]
于 2008-10-19T07:14:33.060 回答
4

使用分而治之的策略。D&C 算法是递归算法。要使用 D&C 解决这个问题,有两个步骤:

  1. 找出基本情况。这应该是最简单的情况。
  2. 划分或减少您的问题,直到它成为基本情况。

第 1 步:找出基本情况。你能得到的最简单的清单是什么?如果你得到一个包含 0 或 1 个元素的列表,这很容易总结。

if len(l) == 0:  #base case
    return []

第 2 步:每次递归调用都需要靠近一个空列表

recursive(l)    #recursion case

例如

l = [1,2,4,6]
def recursive(l):
    if len(l) == 0:
        return []  # base case
    else:
        return [l.pop()] + recursive(l)  # recusrive case


print recursive(l)

>[6,4,2,1]

资料来源:Grokking 算法

于 2017-07-18T10:46:29.090 回答
3

这个就地反转。(当然迭代版本会更好,但它必须是递归的,不是吗?)

def reverse(l, first=0, last=-1):
    if first >= len(l)/2: return
    l[first], l[last] = l[last], l[first]
    reverse(l, first+1, last-1)

mylist = [1,2,3,4,5]
print mylist
reverse(mylist)
print mylist
于 2008-10-20T00:11:43.290 回答
2
def revList(alist):
    if len(alist) == 1:       
        return alist #base case
    else:
        return revList(alist[1:]) + [alist[0]]

print revList([1,2,3,4])
#prints [4,3,2,1]
于 2016-01-30T04:21:54.567 回答
2

用于反转列表的递归函数。

def reverseList(lst):
    #your code here
    if not lst:
        return []
    return [lst[-1]] + reverseList(lst[:-1])


print(reverseList([1, 2, 3, 4, 5]))
于 2019-10-30T06:35:15.400 回答
1
def reverse(q):
    if len(q) != 0:
        temp = q.pop(0)
        reverse(q)
        q.append(temp)
    return q
于 2010-01-20T22:36:52.027 回答
1

看起来更简单:

    def reverse (n):
        if not n: return []
        return [n.pop()]+reverse(n)
于 2017-03-07T09:56:20.617 回答
0

取第一个元素,递归地反转列表的其余部分,并将第一个元素附加到列表的末尾。

于 2008-10-19T07:02:44.113 回答
0
def reverseList(listName,newList = None):
if newList == None:
    newList = []
if len(listName)>0:
    newList.append((listName.pop()))
    return reverseList(listName, newList)
else:
    return newList

打印反向列表([1,2,3,4])[4,3,2,1]

于 2016-02-28T06:09:27.143 回答
0

使用可变默认参数和递归:

def hello(x,d=[]):
    d.append(x[-1])
    if len(x)<=1:
        s="".join(d)
        print(s)

    else:
        return hello(x[:-1])

hello("word")

附加信息

x[-1]    # last item in the array
x[-2:]   # last two items in the array
x[:-2]   # everything except the last two items

递归部分是hello(x[:-1])它再次调用 hello 函数的地方x[:-1]

于 2016-10-11T13:05:51.017 回答
0

这也将反转嵌套列表!

A = [1, 2, [31, 32], 4, [51, [521, [12, 25, [4, 78, 45], 456, [444, 111]],522], 53], 6]

def reverseList(L):

    # Empty list
    if len(L) == 0:
        return

    # List with one element
    if len(L) == 1:

        # Check if that's a list
        if isinstance(L[0], list):
            return [reverseList(L[0])]
        else:
            return L

    # List has more elements
    else:
        # Get the reversed version of first list as well as the first element
        return reverseList(L[1:]) + reverseList(L[:1])

print A
print reverseList(A)

Padmal 的博客

于 2016-10-24T00:42:15.810 回答
0

rev您可以通过一次交换第一个和最后一个元素并在列表中间递归调用来将递归深度减少一半:

lks=[2,7,3,1,9,6,5]
def rev(lks):
    if len(lks)<2:
        return lks
    return [lks[-1]]+rev(lks[1:-1])+[lks[0]]
print(rev(lks))
于 2021-06-13T17:56:04.347 回答
0

您正在寻找的答案在函数内部。剩下的只是看看(或者如果你想比较)不同算法所花费的时间。

import time
import sys

sys.setrecursionlimit(10**6)


def reverse(ls1):
    if len(ls1) <= 1:
        return ls1
    else:
        ls1[0], ls1[-1] = ls1[-1], ls1[0]
        return [ls1[0]] + reverse(ls1[1:-1]) + [ls1[-1]]


ls = [*range(2000)]
start_time = time.time()
print(reverse(ls))
stop_time = time.time()
print(f"Total time taken: {(stop_time - start_time) * 1000} msec.")
于 2021-06-20T14:28:59.550 回答
-1

为什么不:

a = [1,2,3,4,5]
a = [a[i] for i in xrange(len(a)-1, -1, -1)] # now a is reversed!
于 2016-10-11T13:16:19.467 回答
-1

如果它是一个数字列表,最简单的反转方法就是。这也适用于字符串,但不推荐。

l1=[1,2,3,4]
l1 = np.array(l1)
assert l1[::-1]==[4,3,2,1]

如果您不想将其保留为 numpy 数组,则可以将其传递到列表中

l1 = [*l1]

再次,我不建议将它用于字符串列表,但如果你真的想的话,你可以这样做。

于 2020-11-22T17:36:05.050 回答
-1
def reverse_array(arr, index):
    if index == len(arr):
        return

    if type(arr[index]) == type([]):
        reverse_array(arr[index], 0)

    current = arr[index]
    reverse_array(arr, index + 1)
    arr[len(arr) - 1 - index] = current
    return arr

if __name__ == '__main__':
    print(reverse_array([[4, 5, 6, [4, 4, [5, 6, 7], 8], 8, 7]], 0))
于 2021-03-20T18:09:26.583 回答
-1
def disp_array_reverse(inp, idx=0):
    if idx >= len(inp):
        return
    disp_array_reverse(inp, idx+1)
    print(inp[idx])
于 2021-06-01T18:28:28.027 回答