32

A 有一个真正的问题(和头痛)的任务......

我在上一门入门编程课,我必须编写一个函数,给定一个列表,它将返回它所达到的“最大”深度......例如:[1,2,3] 将返回 1,[ 1,[2,3]] 将返回 2...

我已经写了这段代码(这是我能得到的最好的T_T)

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

但是,它显然不像它应该的那样工作,因为如果有列表不计入最大深度,它仍然会提高计数器......

例如:当我使用带有 [1,2,[3,4],5,[6],7] 的函数时,它应该返回 2,但它返回 3...

任何想法或帮助将不胜感激^^非常感谢!我已经为此苦苦挣扎了好几个星期了...

4

14 回答 14

36

这是编写函数的一种方法

depth = lambda L: isinstance(L, list) and max(map(depth, L))+1

我认为您缺少的想法是使用max()

于 2011-05-18T02:10:19.970 回答
16

让我们首先稍微改一下您的要求。

列表的深度比其子列表的最大深度大一。

现在,这可以直接翻译成代码:

def depth(l):
    if isinstance(l, list):
        return 1 + max(depth(item) for item in l)
    else:
        return 0
于 2011-05-18T02:12:30.780 回答
7

递归很容易

def flat(l):
    depths = []
    for item in l:
        if isinstance(item, list):
            depths.append(flat(item))
    if len(depths) > 0:
        return 1 + max(depths)
    return 1
于 2011-05-18T02:10:44.490 回答
6

广度优先,没有递归,它也适用于其他序列类型:

from collections import Sequence
from itertools import chain, count

def depth(seq):
    for level in count():
        if not seq:
            return level
        seq = list(chain.from_iterable(s for s in seq if isinstance(s, Sequence)))

相同的想法,但内存消耗要少得多:

from collections import Sequence
from itertools import chain, count

def depth(seq):
    seq = iter(seq)
    try:
        for level in count():
            seq = chain([next(seq)], seq)
            seq = chain.from_iterable(s for s in seq if isinstance(s, Sequence))
    except StopIteration:
        return level
于 2011-05-18T05:23:03.803 回答
2

辱骂方式:说你的名单叫mylist

mybrackets = map(lambda x: 1 if x=='[' else -1, [x for x in str(mylist) if x=='[' or x==']'])  
maxdepth = max([sum(mybrackets[:i+1]) for i in range(len(mybrackets))])

这会将您的列表转换为左括号和右括号的列表,然后找到在相应右括号出现之前出现的最大数量的左括号。

于 2011-05-18T02:44:23.990 回答
2

一种不需要任何额外模块并且无论深度如何都具有相同速度的方式:

def depth(nested):
    instring = False
    count = 0
    depthlist = []
    for char in repr(nested):
        if char == '"' or char == "'":
            instring = not instring
        elif not instring and ( char == "[" or char == ")" ):
            count += 1
        elif not instring and ( char == "]" or char == ")" ):
            count -= 1
        depthlist.append(count)
    return(max(depthlist))

基本上,它的作用是使用 . 将列表转换为字符串repr()。然后对于这个字符串中的每个字符等于“ (”或“ [”它增加变量count。对于右括号,它会减少count。然后它返回count已达到的最大值。

于 2014-05-07T17:37:17.543 回答
2

在一行python中做到了:)

请享用

def f(g,count=0): return count if not isinstance(g,list) else max([f(x,count+1) for x in g])
于 2011-05-18T02:21:56.750 回答
1

如果您正在寻找快速解决方案

def getDepth(matrix):
    try:
        len(matrix)
        return getDepth(matrix[0]) + 1
    except:
        return 0
于 2020-06-23T02:18:04.493 回答
1

我为每个可迭代扩展了hammar 的答案(默认情况下禁用字符串):

def depth(arg, exclude=None):
    if exclude is None:
        exclude = (str, )

    if isinstance(arg, tuple(exclude)):
        return 0

    try:
        if next(iter(arg)) is arg:  # avoid infinite loops
            return 1
    except TypeError:
        return 0

    try:
        depths_in = map(lambda x: depth(x, exclude), arg.values())
    except AttributeError:
        try:
            depths_in = map(lambda x: depth(x, exclude), arg)
        except TypeError:
            return 0

    try:
        depth_in = max(depths_in)
    except ValueError:
        depth_in = 0

    return 1 + depth_in
于 2016-02-29T11:16:39.217 回答
1

Numpy中,您可以将数据结构转换为 anumpy array并使用其库函数。arr.shape给出每层的长度,所以我们可以len()得到结构的形状和深度:

import numpy as np

def f( lists )
  arr = np.array( lists )
  return len(arr.shape)

f( [[[1,2],[3,4]],[[3,4],[5,6]]] ) # results in 3
f( [[1,2],[3,4]] ) # results in 2
f( [1,2] )  # results in 1
f( [] )  # results in 1

形状的 Numpy 文档:https ://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.shape.html

于 2019-07-09T09:04:04.160 回答
0

对所说内容的简短补充,因此它也可以处理空列表:

def list_depth(list_of_lists):
    if isinstance(list_of_lists, list):
        if(len(list_of_lists) == 0):
            depth = 1
        else:
            depth = 1 + max([list_depth(l) for l in list_of_lists])
    else:
        depth = 0
    return depth
于 2015-09-21T16:31:44.387 回答
0

@John 的解决方案非常好,但是要解决空列表的情况,例如[],[[]]或进一步的嵌套列表,您可能需要执行以下操作

depth = lambda L: isinstance(L, list) and (max(map(depth, L)) + 1) if str(L) else 1
于 2016-09-27T11:31:39.140 回答
0

您也可以仅使用 python 递归地执行此操作:

def depth(L,d):
    max = d
    for i in range(len(L)):
        if type(L[i])==list :
            a = depth(L[i],d+1)
            if a>max :
                 max = a
    return(max)

这个函数是递归的,它的作用是它只是进入列表的最大深度,计算列表的深度,当它向上爬时,它只保留所有嵌套列表中注册的最大深度。

于 2020-08-09T15:06:59.877 回答
0

让我们坚持原来的、相当优雅的解决方案,并使用max让它工作。许多其他解决方案使用 lambda 表达式或需要外部库。这个使用“纯”python 并保持简单。

def depth(lst):
    d = 0
    for item in lst:
        if isinstance(item, list):
            d = max(depth(item), d)
    return d + 1

奖励:此解决方案计算空列表并避免遍历字符串的陷阱(前提是您要计算空列表)。

于 2022-01-02T04:22:11.913 回答