【问题标题】:How to find the number of nested lists in a list?如何查找列表中嵌套列表的数量?
【发布时间】:2015-01-08 17:27:36
【问题描述】:

该函数接受一个列表并返回一个 int,具体取决于列表中有多少个列表,不包括列表本身。 (为简单起见,我们可以假设所有内容都是整数或列表。)

例如:

x=[1,2,[[[]]],[[]],3,4,[1,2,3,4,[[]] ] ]

count_list(x) # would return 8

我认为使用递归会有所帮助,但我不确定如何实现它,这是我目前所拥有的。

def count_list(a,count=None, i=None):

    if count==None and i==None:
        count=0
        i=0
    if i>len(a)
        return(count)
    if a[i]==list
       i+=1
       count+=1
       return(count_list(a[i][i],count))
    else:
        i+=1
        return(count_list(a[i]))

【问题讨论】:

  • 一个明显错误的答案怎么样? str(x).count("[") - 1
  • 只要任何列表中都没有字符串,该解决方案可能不会比递归更糟糕。如果任何列表中有字符串,那么您可能有一个包含 "[" 的字符串,这会破坏一切。
  • def 行上,应该有单等号而不是双等号。

标签: python list python-3.x recursion


【解决方案1】:

这似乎可以完成工作:

def count_list(l):
    count = 0
    for e in l:
        if isinstance(e, list):
            count = count + 1 + count_list(e)
    return count

【讨论】:

  • 好吧,从不了解 Python 的人的角度来看,我认为你的更具可读性,尽管他们显然做同样的事情。在我看来,对于新手程序员来说,可读性胜过节省一两行;)
【解决方案2】:

您可以使用如下递归函数:

In [14]: def count(l):
    ...:     return sum(1 + count(i) for i in l if isinstance(i,list))
    ...: 

In [15]: 

In [15]: x=[1,2,[[[]]],[[]],3,4,[1,2,3,4,[[]] ] ]

In [16]: count(x)
Out[16]: 8

【讨论】:

    【解决方案3】:

    没有循环的函数式解决方案。递归处理列表的第一个元素和列表的尾部。为遇到的每个空列表添加一个(也就是说,一旦我们处理完某个列表,它的尾部就变为空,我们将结果加 1)。并为列表本身减去 1。

    def number_of_lists(x):
        f = lambda x: 0 if not isinstance(x,list) else (f(x[0]) + f(x[1:]) if len(x) else 1)
        return f(x) - 1
    

    结果:

    x=[1,2,[[[]]],[[]],3,4,[1,2,3,4,[[]] ] ]
    number_of_lists(x)
    >> 8
    

    【讨论】:

      【解决方案4】:

      这是一个非递归的解决方案:

      1. 首先,将列表中的每一项放入堆栈中
      2. 继续从堆栈中弹出一个项目,直到它用完
      3. 如果项目是列表:a) 计算它,b) 将每个项目推入堆栈

      代码:

      def count_list(lst):
          """ Given a master list, count the number of sub-lists """
          stack = lst[:]
          count = 0
          while stack:
              item = stack.pop()
              if isinstance(item, list):
                  # If the item is a list, count it, and push back into the
                  # stack so we can process it later
                  count += 1
                  stack.extend(item)
          return count
      

      【讨论】:

        【解决方案5】:

        我喜欢这种尾递归解决方案,虽然它在 Python 中用处不大……

        def count_lists(l, counter):
            if (len(l) == 0):
                return counter
            else:
                e = l.pop(0)
                if (isinstance(e, list)):
                    l.extend(e)
                    return count_lists(l, 1 + counter)
                else:
                    return count_lists(l, counter)
        
        x=[1,2,[[[]]],[[]],3,4,[1,2,3,4,[[]]]]
        print(count_lists(x, 0))
        

        【讨论】:

        • 我不擅长算法——你用l.pop(0)而不是l.pop()有什么原因吗?如果它可以工作,那么后者会更快。
        • 是的,两者之间是有区别的。 pop(0) 删除列表中的第一项,而pop() 删除最后一项。关于性能的好点,算法可以改为使用 pop()。
        【解决方案6】:
        lst = [1,2,[[[]]],[[]],3,4,[1,2,3,4,["[[[[[][[[[[[[[[[[[["] ] ]
        
        strlst = re.sub("'.*?'", '',str(lst))
        print(strlst.count("[")-1)
        

        将列表设为字符串将允许您对 [] 的数量使用计数功能,从而为您提供答案

        但如果列表中的字符串包含[],它们将被包含在内 所以使用正则表达式删除列表中的所有字符串可以消除这个问题

        【讨论】:

        • 遗憾的是,如果你有带有[ 的字符串,它就不起作用:Try it online!
        • 我使用了 tio.run,它似乎可以正常工作,但由于列表中的字符串包含 [ 我可以看到问题
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多