Python函数以递归方式拆分和添加列表

时间:2016-03-16 13:43:24

标签: python recursion

我在python中编写一个函数会遇到一个列表,将其拆分为两个相等的边,然后递归地添加每一半中的每个元素。最后归还两半的总和。

def sumLists(aList):
    half = len(aList)//2
    leftHalf = aList[half:]
    rightHalf = aList[:half]
    if len(aList) == 1:
        return aList[0]
    else:
        sumOfLeft = sumLists(leftHalf[1:])
        resultLeft = leftHalf[0] + sumOfLeft
        sumOfRight = sumLists(rightHalf[1:])
        resultRight = rightHalf[0] + sumOfRight
        return resultLeft + resultRight

感谢任何提示,谢谢!

3 个答案:

答案 0 :(得分:3)

您过度复杂else块。您无需在sumListsleftHalf[1:]上致电rightHalf[1:]并手动添加第一个相应的元素;只需在完整列表上调用sumLists即可。

这种切片是造成RuntimeError的原因。长度为1的leftHalf长度为leftHalf[1:]。但是你的函数永远会递归长度为零的长度,因为你没有为那个场景编写if个案例。

您可以重写else,以便不需要切片:

def sumLists(aList):
    half = len(aList)//2
    leftHalf = aList[half:]
    rightHalf = aList[:half]
    if len(aList) == 1:
        return aList[0]
    else:
        return sumLists(leftHalf) + sumLists(rightHalf)

...或者你可以为空列表添加一个特殊情况:

def sumLists(aList):
    half = len(aList)//2
    leftHalf = aList[half:]
    rightHalf = aList[:half]
    if len(aList) == 0:
        return 0
    elif len(aList) == 1:
        return aList[0]
    else:
        sumOfLeft = sumLists(leftHalf[1:])
        resultLeft = leftHalf[0] + sumOfLeft
        sumOfRight = sumLists(rightHalf[1:])
        resultRight = rightHalf[0] + sumOfRight
        return resultLeft + resultRight

或两者:

def sumLists(aList):
    half = len(aList)//2
    leftHalf = aList[half:]
    rightHalf = aList[:half]
    if len(aList) == 0:
        return 0
    if len(aList) == 1:
        return aList[0]
    else:
        return sumLists(leftHalf) + sumLists(rightHalf)

答案 1 :(得分:0)

也许我误读了你的问题,但你真的需要在一个函数中做这两件事吗?

要递归地汇总列表,您可以定义空列表(您的基本情况)具有总和0.任何非空列表都具有第一个元素加上余数之和的总和("列表的尾部"):

def sumList(a):
  return 0 if not a else a[0] + sumList(a[1:])

要递归地拆分列表,您可以跟踪" left"和"对"名单。左侧列表开始作为您的输入,右侧列表为空。然后递归地将左侧列表的最后一个元素添加到右侧列表中,直到右侧列表不再短于左侧:

def splitList(a, b=None):
  b = b or []
  return (a, b) if len(a) <= len(b) else splitList(a[:-1], [a[-1]] + b)

我怀疑在Python中传递切片是非常低效的,所以最好还是传递索引,例如。

def sumList(a, idx=None):
  idx = idx or 0
  return 0 if idx >= len(a) else a[idx] + sumList(a, idx+1)

答案 2 :(得分:0)

我认为aList[half:]是右侧,aList[:half]是左侧,是不是? 以下代码将列表左右两侧相加,希望这可以解决您的问题。

def sumlist(l):
    if not l or not isinstance(l, list):
        return 0  # or return other default value.
    if len(l) == 1:
        return l[0]
    half = len(l) // 2
    left = l[:half]  # left
    right = l[-half:]  # right
    return sumlist(left) + sumlist(right)

试验:

l = [1,2,3,4,5,6,7,8,9]
result = sumlist(l)
print(result)  # 40