【问题标题】:How do I reverse a list using recursion in Python?如何在 Python 中使用递归来反转列表?
【发布时间】:2010-09-17 23:36:55
【问题描述】:

我想要一个函数,它会返回给定列表的逆向函数——使用递归。我该怎么做?

【问题讨论】:

    标签: python list recursion


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      您可以通过一次交换第一个和最后一个元素并在列表中间递归调用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))
      

      【讨论】:

      • 这是一个有趣的方法,同时交换两端。我喜欢它。
      【解决方案3】:
      def disp_array_reverse(inp, idx=0):
          if idx >= len(inp):
              return
          disp_array_reverse(inp, idx+1)
          print(inp[idx])
      

      【讨论】:

        【解决方案4】:
        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))
        

        【讨论】:

          【解决方案5】:

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

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

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

          l1 = [*l1]
          

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

          【讨论】:

            【解决方案6】:

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

            def reverseList(lst):
                #your code here
                if not lst:
                    return []
                return [lst[-1]] + reverseList(lst[:-1])
            
            
            print(reverseList([1, 2, 3, 4, 5]))
            

            【讨论】:

              【解决方案7】:

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

              【讨论】:

                【解决方案8】:

                看起来更简单:

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

                【讨论】:

                  【解决方案9】:

                  这也将反转嵌套列表!

                  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's BLOG

                  【讨论】:

                    【解决方案10】:

                    为什么不:

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

                    【讨论】:

                      【解决方案11】:

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

                      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函数

                      【讨论】:

                        【解决方案12】:
                        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]

                        【讨论】:

                          【解决方案13】:
                          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]
                          

                          【讨论】:

                            【解决方案14】:
                            def reverse(q):
                                if len(q) != 0:
                                    temp = q.pop(0)
                                    reverse(q)
                                    q.append(temp)
                                return q
                            

                            【讨论】:

                              【解决方案15】:

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

                              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
                              

                              【讨论】:

                                【解决方案16】:

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

                                【讨论】:

                                • 在“请不要在实际代码中这样做”的内容上不同意您的意见。在这种特殊情况下,Python 不优化尾调用并不重要,因为没有 CPS 的列表反转不是尾递归。
                                【解决方案17】:

                                更明确一点:

                                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]
                                

                                【讨论】:

                                  【解决方案18】:

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

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

                                  【讨论】:

                                    【解决方案19】:

                                    诀窍是在 递归之后加入:

                                    向后定义(l): 如果不是我: 返回 x, y = l[0], l[1:] 向后返回(y) + [x]

                                    【讨论】:

                                      【解决方案20】:

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

                                      【讨论】:

                                        猜你喜欢
                                        • 2016-03-21
                                        • 2022-08-12
                                        • 2014-04-13
                                        • 1970-01-01
                                        • 2020-12-04
                                        • 2013-04-13
                                        • 2013-04-22
                                        • 1970-01-01
                                        • 2019-11-18
                                        相关资源
                                        最近更新 更多