【问题标题】:Recursive function that takes in one list and returns two lists接受一个列表并返回两个列表的递归函数
【发布时间】:2018-11-12 21:19:56
【问题描述】:

我被要求定义一个递归函数,该函数接收一个列表,然后将该列表的值分配给另外两个列表以这样的方式,当你取这两个列表中的每一个的总和,您会得到两个彼此非常接近的结果。

示例

如果我跑:

print(proximity_lists([5, 8, 8, 9, 17, 21, 24, 27, 31, 41]))

我得到了两个列表:

[31, 27, 21, 9, 8]          #sum = 96

[41, 24, 17, 8, 5]          #sum = 95

我就是这样做的,但是我无法理解如何在递归函数中返回两个列表。到目前为止,我对必须返回一个列表的条件感到满意。

这是我目前的代码:

def proximity_lists(lst, lst1 = [], lst2 = []):
    """
    parameters : lst of type list;
    returns : returns two lists such that the sum of the elements in the lst1
              is in the proximity of the sum of the elements in the lst2
    """
    if not lst:
        if abs(sum(lst1)-sum(lst2)) in range(5):         
            return lst1, lst2
    else:
        return {Not sure what to put here} + proximity_lists(lst[1:])

range() 而言,它可以接受任何参数,只要它是他们可以彼此接近的最接近的。我选择了 5,因为根据上面的示例输出,它们之间的差异是 1。

我需要补充一点,这必须在没有任何模块的帮助下完成。它是使用简单的函数完成的。

【问题讨论】:

  • 列表总是偶数?子列表总是相同的大小?最小子列表大小?我的意思是 [8] 和 [8] 可能是最合适的。
  • 没有指定这样的条件,所以我想只要两个列表的总和彼此最接近,什么都会发生。
  • 对不起,请您问一个具体的问题。我了解您的示例以及对您的要求,但请说明您需要帮助的问题。
  • @trs 我发布了我的代码,以便了解如何获得该输出

标签: python list recursion


【解决方案1】:

就性能(指数复杂度)而言,这可能不是最佳解决方案,但也许它可以帮助您入门:

def proximity_lists(values):
    def _recursion(values, list1, list2):
        if len(values) == 0:
            return list1, list2
        head, tail = values[0], values[1:]
        r1, r2 = _recursion(tail, list1 + [head], list2)
        s1, s2 = _recursion(tail, list1, list2 + [head])
        if abs(sum(r1) - sum(r2)) < abs(sum(s1) - sum(s2)):
            return r1, r2
        return s1, s2

    return _recursion(values, [], [])

values = [5, 8, 8, 9, 17, 21, 24, 27, 31, 41]
s1, s2 = proximity_lists(values)
print(sum(s1), sum(s2))
print(s1)
print(s2)

96 95
[24, 31, 41]
[5, 8, 8, 9, 17, 21, 27]

如果不能有封装函数,直接调用_recursion(values, [], [])即可。

【讨论】:

    【解决方案2】:

    您可以找到第一个列表的原始输入的所有排列,并过滤原始输入以获得第二个。此答案假定“非常接近”意味着两个列表之和之间的差异小于或等于1

    from collections import Counter
    
    def close_proximity(d, _dist = 1):
      def _valid(c, _original):
        return abs(sum(c) - sum([i for i in _original if i not in c])) <= _dist
      def combos(_d, current = []):
        if _valid(current, _d) and current:
          yield current
        else:
          for i in _d:
            _c1, _c2 = Counter(current+[i]), Counter(_d)
            if all(_c2[a] >= b for a, b in _c1.items()):
              yield from combos(_d, current+[i])
      return combos(d)
    
    start = [5, 8, 8, 9, 17, 21, 24, 27, 31, 41]
    t = next(close_proximity(start))
    _c = [i for i in start if i not in t]
    print(t, _c, abs(sum(t) - sum(_c)))
    

    输出:

    [5, 8, 8, 9, 17, 21, 27] [24, 31, 41] 1
    

    【讨论】:

      【解决方案3】:

      我无法理解如何在一个 递归函数。

      这是一个简单的解决方案,它可以生成原始结果,但没有额外的参数、内部函数等。它只是不断地从下一个可用值增加较小的列表:

      def proximity_lists(array):
          if array:
              head, *tail = array
      
              a, b = proximity_lists(tail)
      
              ([a, b][sum(b) < sum(a)]).append(head)
      
              return [a, b]
      
          return [[], []]
      

      用法

      >>> proximity_lists([5, 8, 8, 9, 17, 21, 24, 27, 31, 41])
      [[41, 24, 17, 8, 5], [31, 27, 21, 9, 8]]
      >>> 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-20
        • 2017-02-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-14
        • 2016-06-21
        相关资源
        最近更新 更多