【问题标题】:How do i sum up 2 halves of a list recursively我如何递归地总结列表的两半
【发布时间】:2021-12-29 20:37:22
【问题描述】:

我需要先将列表分成两半,然后用递归对这两半求和

def merge_sum(list):
    
    middle = int(len(list)-1)//2
    first_half = merge_sum(list[:middle])
    second_half = merge_sum(list[middle:])
    return first_half + second_half

print(merge_sum([1,2,3,4,5,6]))

【问题讨论】:

  • 当列表长度为 1 或为空时,您需要基本情况​​

标签: python list recursion


【解决方案1】:

考虑为lst 的长度为10 时添加几个基本情况:

def merge_sum(lst):
    if not lst: return 0
    if len(lst) == 1: return lst[0]
    middle = len(lst) // 2
    first_half = merge_sum(lst[:middle])
    second_half = merge_sum(lst[middle:])
    return first_half + second_half

print(merge_sum([1, 2, 3, 4, 5, 6]))

输出:

21

【讨论】:

    【解决方案2】:

    当列表变得足够小时,您的递归函数需要基本情况​​,并且您需要确保每次基本情况未命中时,列表都会变小。中点应该是长度的一半,而不是一半(长度减一)——否则当列表长度达到 2 个元素时,你的中点将为 0 ((2-1)//2 == 0),你将永远无法进一步划分它。

    >>> def merge_sum(nums):
    ...     if len(nums) == 1:
    ...         return nums[0]
    ...     if len(nums) == 0:
    ...         return 0
    ...     middle = len(nums)//2
    ...     return merge_sum(nums[:middle]) + merge_sum(nums[middle:])
    ... 
    >>> merge_sum([1, 2, 3, 4, 5, 6])
    21
    

    请注意,调用参数list 很麻烦,因为list 已经是Python 中列表类型的名称,覆盖它可能会破坏您的代码(或至少使其难以阅读)。

    【讨论】:

      【解决方案3】:

      那些list[middle:] 是列表的不必要的昂贵副本。递归是一个控制结构,一个循环,你可以通过沿着同一个列表结构移动计数器来实现:

      def merge_left(numbers, index, total=0):
        if index < 0:
          return total
        else:
          return merge_left(numbers, (index-1), (total+numbers[index]))
      
      def merge_right(numbers, index, total=0):
        if index == len(numbers):
          return total
        else:
          return merge_right(numbers, (index+1), (total+numbers[index]))
      
       
      def merge_sum(numbers):
        
          middle = len(numbers)//2
          return merge_left(numbers, middle-1) + merge_right(numbers, middle)
      
      print(merge_sum([1,2,3,4,5,6]))
      

      这比其他答案的代码要多得多,但我认为这使左右区别更加清晰。它每次通过循环时传递的只是一个索引和一个运行总计。

      很可能将它们组合成一个函数,但是它需要一种方法来指示方向和调整索引,这使得它不太好。

      【讨论】:

        猜你喜欢
        • 2015-09-07
        • 2021-03-27
        • 1970-01-01
        • 2023-03-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-09
        • 1970-01-01
        相关资源
        最近更新 更多