【问题标题】:How can I get the total number of elements in my arbitrarily nested list of lists?如何获取任意嵌套列表中的元素总数?
【发布时间】:2015-03-01 22:11:09
【问题描述】:

我有一个分配给变量my_list 的列表。 my_list 的值为[[1,2,3],[3,5,[2,3]], [[3,2],[5,[4]]]]。我需要找到 my_list 的长度,但 len(my_list) 只返回 3。我希望它返回 11。是否有任何 Python 函数可以返回 my_list 嵌套列表的完整长度等等。

例子:

Input
[[1,2,3],[3,5,[2,3]], [[3,2],[5,[4]]]]

Output
11

我希望这不仅适用于数字,也适用于字符串。

【问题讨论】:

  • 这应该是一个规则。我们在谈论多少“嵌套”?
  • 您希望它与可能包含字符串的嵌套列表一起使用,还是列表只包含数字?
  • @michaelpri 那么你的问题有点误导,“找到所有嵌套列表的长度?”
  • 这是一个展平任意嵌套列表的好函数:stackoverflow.com/a/2158532/4014959。使用它来展平您的嵌套列表,然后您只需要获取展平列表的len()
  • @RusI 通常,在您运行生成器之前,您不知道生成器会生成多少项目,并且有些生成器永远不会停止生成项目。如果您有一个知道大小有限的生成器,您可以从中生成一个列表,然后在该列表上调用len()。例如,len(list(flatten(deep_nested_list)))

标签: python list python-2.7 nested-lists


【解决方案1】:

此函数计算列表的长度,将列表以外的任何对象计算为长度 1,并在列表项上递归以找到展平长度,并且可以在解释器最大堆栈深度的任何嵌套程度下工作。

def recursive_len(item):
    if type(item) == list:
        return sum(recursive_len(subitem) for subitem in item)
    else:
        return 1

注意:根据这将如何使用,最好检查项目是否可迭代而不是检查它是否具有list类型,以便正确判断元组的大小等。但是,检查对象是否可迭代将产生计算字符串中每个字符的副作用,而不是给字符串长度 1,这可能是不可取的。

【讨论】:

  • 您应该编辑 if type(item) == list or type(item) == tuple or type(item)==dict 等。
  • if isinstance(item, collections.Iterable) and not isinstance(item,basestring):
  • 您也可以将元组传递给 issinstance if isinstance(item, (list,tuple))
【解决方案2】:

破解解决方案,必须有人发布。将列表转换为字符串(将繁重的工作/递归留给__str__ 运算符)然后计算逗号,加 1。

>>> my_list = [[1,2,3],[3,5,[2,3]], [[3,2],[5,[4]]]]
>>> str(my_list).count(",")+1
11

(适用于整数和浮点数,当然对于字符串会失败,因为它们可以包含逗号)

编辑:这个 hack 不考虑空列表:我们必须删除 [] 元素:

>>> my_list = [[1,2,3],[3,5,[2,3]], [[3,2],[5,[4],[]]]]  # added empty list at the end
>>> s = str(my_list)
>>> s.count(",")-s.count("[]")+1   # still 11

【讨论】:

  • 当列表可能有,时不适用于字符串列表
  • 自 2017 年 10 月以来在我的回答中:字符串当然会失败,因为它们可以包含逗号
【解决方案3】:

作为替代方案,您可以将 flattenlen 一起使用:

from compiler.ast import flatten

my_list = [[1,2,3],[3,5,[2,3]], [[3,2],[5,[4]]]]

len(flatten(my_list))
11

PS。感谢@thefourtheye 指出,请注意:

自 2.6 版起已弃用:编译器包已在 Python 3 中删除。

可以在这里找到替代方案:Python 3 replacement for deprecated compiler.ast flatten function

【讨论】:

  • compiler.ast.flatten 早就被弃用了。
【解决方案4】:

您实际上是在寻找一种计算树中叶子数量的方法。

 def is_leaf(tree):
        return type(tree) != list

def count_leaves(tree):
    if is_leaf(tree):
        return 1
    else:
        branch_counts = [count_leaves(b) for b in tree]
        return sum(branch_counts)

count_leaves 函数通过递归计算分支的 branch_counts 来计算树中的叶子,然后对这些结果求和。基本情况是当树是一片叶子时,它是一棵有 1 片叶子的树。叶子的数量与树的长度不同,这是它的分支数。

【讨论】:

    【解决方案5】:

    这是一个替代解决方案,它可能不是那么高效,因为它填充了一个新的扁平列表,该列表在最后返回:

    def flatten_list(ls, flattened_list=[]):
        for elem in ls:
            if not isinstance(elem, list): 
                flattened_list.append(elem)
            else:
                flatten_list(elem, flattened_list)
        return flattened_list
    

    flatten_list 直观地展平列表,然后可以使用len() 函数计算新返回的展平列表的长度:

    len(flatten_list(my_list))
    

    【讨论】:

      【解决方案6】:

      这是我的实现:

      def nestedList(check):
          returnValue = 0
          for i in xrange(0, len(check)):
              if(isinstance(check[i], list)):
                  returnValue += nestedList(check[i])
              else:
                  returnValue += 1
          return returnValue
      

      【讨论】:

        【解决方案7】:

        这是我最好的尝试,利用递归,只使用标准库和可视化。我尽量不使用自定义库

        def listlength(mylist, k=0, indent=''):
            for l1 in mylist:
                if isinstance(l1, list):
                    k = listlength(l1, k, indent+'  ')
                else:
                    print(indent+str(l1))
                    k+=1
            return k
        
        a = [[1,2,3],[3,5,[2,3]], [[3,2],[5,[4]]]]
        listlength(a)
        # 11
        

        为了更好的衡量

        a = []
        x = listlength(a)
        print('length={}'.format(x))
        # length=0
        
        
        
        a = [1,2,3]
        x = listlength(a)
        print('length={}'.format(x))
        #1
        #2
        #3
        #length=3
        
        
        a = [[1,2,3]]
        x = listlength(a)
        print('length={}'.format(x))
        #  1
        #  2
        #  3
        #length=3
        
        
        a = [[1,2,3],[1,2,3]]
        x = listlength(a)
        print('length={}'.format(x))
        #  1
        #  2
        #  3
        #  1
        #  2
        #  3
        #length=6
        
        a = [1,2,3, [1,2,3],[1,2,3]]
        x = listlength(a)
        print('length={}'.format(x))
        #1
        #2
        #3
        #  1
        #  2
        #  3
        #  1
        #  2
        #  3
        #length=9
        
        
        a = [1,2,3, [1,2,3,[1,2,3]]]
        x = listlength(a)
        print('length={}'.format(x))
        #1
        #2
        #3
        #  1
        #  2
        #  3
        #    1
        #    2
        #    3
        #length=9
        
        
        a = [ [1,2,3], [1,[1,2],3] ]
        x = listlength(a)
        print('length={}'.format(x))
        #  1
        #  2
        #  3
        #  1
        #    1
        #    2
        #  3
        #length=7
        

        【讨论】:

          猜你喜欢
          • 2022-10-05
          • 1970-01-01
          • 1970-01-01
          • 2015-10-15
          • 1970-01-01
          • 2017-03-03
          • 2020-01-17
          • 1970-01-01
          • 2021-09-19
          相关资源
          最近更新 更多