【问题标题】:Summing nested lists without recursion in python在python中对没有递归的嵌套列表求和
【发布时间】:2014-05-07 02:27:02
【问题描述】:

给定一个 Python 列表,其元素要么是整数,要么是整数列表(只是我们不知道嵌套的深度),我们如何才能找到列表中每个整数的总和?

找到嵌套只有一层的列表的总和是相当简单的, 但是如果嵌套有两层、三层或更多层怎么办?

我知道最好的方法是递归,但这是一个挑战,我必须在没有递归的情况下做到这一点。

请帮忙!!

【问题讨论】:

  • 你不能在你的问题中添加一些测试用例吗?不难解决,只是没时间给你写测试用例。
  • 这听起来像是一个家庭作业类型的问题,尤其是那里有这样的任意限制。
  • 想一想,问题本质上是扁平化嵌套列表。
  • l = [1,[2,[3,[[[4]]]],5],6,[[7,8]],2]

标签: python recursion sum nested-lists


【解决方案1】:
L = [...]
while any(isinstance(i, list) for i in L):
   L = [j for i in L for j in (i if isinstance(i, list) else [i])]

result = sum(L)

基本上,您遍历外部列表并解压缩任何内部列表的第一级,直到没有剩余内部列表

【讨论】:

    【解决方案2】:

    一种迭代扁平化列表的最易读(并且可能是高性能的,虽然我没有测试过)方法:

    from collections import deque
    
    def iterative_flatten(li):
        nested = deque(li)
        res = []
        dq = deque()
        while nested or dq:
            x = dq.pop() if dq else nested.popleft()
            dq.extend(reversed(x)) if isinstance(x, list) else res.append(x)
        return res
    

    使用双端队列来避免来自list.pop(0) 的讨厌的 O(n**2) 行为。您可以通过制作反向副本并从末尾弹出来获得相同的结果,但如果您只使用双端队列和popleft,我发现代码更容易理解。在类似的注释中,如果您想就地改变列表但速度较慢(出于同样的原因;来自列表 headpopping 是 O (n) 因为底层数组中的每个元素都必须移动)。

    nested = [1,[[2,3],[[4,5],[6]]],[[[[7]]]]]
    
    iterative_flatten(nested)
    Out[116]: [1, 2, 3, 4, 5, 6, 7]
    
    sum(iterative_flatten(nested))
    Out[117]: 28
    

    在它变平之后,求和(希望)是微不足道的:-)

    【讨论】:

      【解决方案3】:

      这是一种解决方案:

      from copy import deepcopy
      
      def recursive_sum(int_list):
          #int_list = deepcopy(int_list)    use this line if don't want to modify original list
          ret = 0
          while len(int_list) > 0:
              elem = int_list.pop(0)
              if type(elem) == int:
                  ret += elem
              elif type(elem) == list:
                  int_list.extend(elem)
              else:
                  raise ValueError
          return ret
      
      testcase = [1,2,3,[4,5,[6,7,8,[9,10]]]]
      print recursive_sum(testcase)    # print 55
      

      基本上,它会弹出输入列表的第一个元素。如果是 Int,则加到 sum;如果是List,则扩展到输入列表的末尾

      【讨论】:

        猜你喜欢
        • 2021-01-12
        • 2018-06-24
        • 1970-01-01
        • 2014-03-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-05
        • 1970-01-01
        相关资源
        最近更新 更多