簡體   English   中英

"如何在 Python 中使用遞歸來反轉列表?"

[英]How do I reverse a list using recursion in Python?

我想要一個函數,它將返回它給出的列表的反向 - 使用遞歸。 我怎樣才能做到這一點?

將列表的第一個元素附加到反向子列表:

mylist = [1, 2, 3, 4, 5]
backwards = lambda l: (backwards (l[1:]) + l[:1] if l else []) 
print backwards (mylist)

更明確一點:

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]

我知道這不是一個有用的答案(盡管這個問題已經得到回答),但在任何實際代碼中,請不要這樣做。 Python 不能優化尾調用,函數調用速度慢,遞歸深度固定,所以至少有 3 個原因為什么要迭代地執行它。

訣竅是遞歸加入:

def backwards(l):
  if not l:
    return
  x, y = l[0], l[1:]
  return backwards(y) + [x]

使用分而治之的策略。 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 算法

這一回原地。 (當然迭代版本會更好,但它必須是遞歸的,不是嗎?)

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

用於反轉列表的遞歸函數。

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


print(reverseList([1, 2, 3, 4, 5]))
def reverse(q):
    if len(q) != 0:
        temp = q.pop(0)
        reverse(q)
        q.append(temp)
    return q

看起來更簡單:

    def reverse (n):
        if not n: return []
        return [n.pop()]+reverse(n)

取第一個元素,遞歸地反轉列表的其余部分,並將第一個元素附加到列表的末尾。

def reverseList(listName,newList = None):
if newList == None:
    newList = []
if len(listName)>0:
    newList.append((listName.pop()))
    return reverseList(listName, newList)
else:
    return newList

打印 reverseList([1,2,3,4]) [4,3,2,1]

使用可變默認參數和遞歸:

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]) ,它在x[:-1]之后再次調用 hello 函數

這也將反轉嵌套列表!

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 的博客

您可以通過一次交換第一個和最后一個元素並在列表中間遞歸調用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))

您正在尋找的答案在函數內部。 其余的只是查看(或者如果您想比較)不同算法所花費的時間。

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.")
def rprint(n):
  if(n==0):
    return
  else:
    print(list1[n-1])
    rprint(n-1)
    

print(" Enter a list element with space ")
list1=input().split()
print(" The reverse of a list ")
n=len(list1)
rprint(n)

為什么不:

a = [1,2,3,4,5]
a = [a[i] for i in xrange(len(a)-1, -1, -1)] # now a is reversed!

我想擁有一個函數,該函數將使用遞歸返回給定列表的相反方向。 我怎樣才能做到這一點?

如果它是一個數字列表,最簡單的反轉方法就是。 這也適用於字符串,但不推薦。

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

如果您不想將其保留為 numpy 數組,則可以將其作為

l1 = [*l1]

同樣,我不建議將它用於字符串列表,但如果您真的願意,您可以這樣做。

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))
def disp_array_reverse(inp, idx=0):
    if idx >= len(inp):
        return
    disp_array_reverse(inp, idx+1)
    print(inp[idx])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM