在寻找任意嵌套列表的最大深度

时间:2015-05-24 19:09:21

标签: python recursion

我目前正在使用Python中的递归函数,而且我遇到了问题。标题是,问题是返回任意嵌套列表的最大深度。

这是我到目前为止所做的:

def depthCount(lst):
    'takes an arbitrarily nested list as a parameter and returns the maximum depth to which the list has nested sub-lists.'

    var = 0

    if len(lst) > 0:

        if type(lst[0]) == list:
            var += 1
            depthCount(lst[1:])

        else:
            depthCount(lst[1:])

    else:
        return var

我觉得问题在于我的递归调用(这可能很明显)。当列表到达结尾时它确实会返回var,但是当我有一个非空列表时,事情就会出错。什么都没有归还。

我切错了吗?我应该在递归调用中的切片之前做些什么吗?

问题也可能出在我的基本情况上。

3 个答案:

答案 0 :(得分:9)

如果它们只是嵌套列表,例如[[[], []], [], [[]]],这是一个不错的解决方案:

def depthCount(lst):
    return 1 + max(map(depthCount, lst), default=0)

如果你不使用引入default参数的Python 3.4,你可以使用一些细微的变化:

def depthCount(lst):
    return len(lst) and 1 + max(map(depthCount, lst))

他们的计算方式也有所不同。第一个将空列表视为深度1,第二个认为深度为0.第一个很容易适应,但是,只需将默认值设为-1。

如果它们不仅仅是嵌套列表,例如[[[1], 'a', [-5.5]], [(6,3)], [['hi']]]),则可以采用以下方式:

def depthCount(x):
    return 1 + max(map(depthCount, x)) if x and isinstance(x, list) else 0

def depthCount(x):
    return int(isinstance(x, list)) and len(x) and 1 + max(map(depthCount, x))

确保您了解后者是如何工作的。如果您还不知道它,它将教您and如何在Python中工作: - )

采取“纯递归”挑战:

def depthCount(x, depth=0):
    if not x or not isinstance(x, list):
        return depth
    return max(depthCount(x[0], depth+1),
               depthCount(x[1:], depth))

当然,额外的论点有点难看,但我认为没关系。

答案 1 :(得分:2)

  

当列表到达结尾时它确实会返回var,但是当我有一个非空列表时,事情就会出错。什么都没有归还。

那是因为你没有return语句,除了else基本情况下的空列表。如果你在没有点击return的情况下脱离函数的末尾,那意味着函数返回None

但是你还有另外一个问题。您正在启动var = 0,然后可能正在执行var += 1 ...但您并未将其传递给递归调用,或者使用递归调用的任何结果。所以递归调用根本没有用处。

你可能意味着什么:

def depthCount(lst):
    'takes an arbitrarily nested list as a parameter and returns the maximum depth to which the list has nested sub-lists.'

    if len(lst) > 0:

        if type(lst[0]) == list:
            return 1 + depthCount(lst[1:])
        else:
            return depthCount(lst[1:])

    else:
        return 0

但这仍然不是真的。列表的深度计数比其最深元素的深度计数多1。只检查它的第二个元素对你没有任何好处;你需要检查所有。所以,你真正想要的是这样的:

def depthCount(lst):
    'takes an arbitrarily nested list as a parameter and returns the maximum depth to which the list has nested sub-lists.'
    if isinstance(lst, list):
        return 1 + max(depthCount(x) for x in lst)
    else:
        return 0

如果你想用第二个递归层替换那个迭代for x in lst,当然你可以,但我看不出有任何理由这样做;它只是使代码更加复杂无缘无故。例如:

def max_child_count(lst):
    if lst:
        return max(depth_count(lst[0]), max_child_count(lst[1:]))
    else:
        return 0

def depth_count(lst):
    if isinstance(lst, list):
        return 1 + max_child_count(lst)
    else:
        return 0

可能仍然不对。它绝对是正确的,例如,[1, [2,3], [4, [5]]]。但它应该怎么做呢,比如[]?我无法从你的问题中说出来。如果它应该返回01,您显然需要适当地更改if。如果这是非法输入,那么它已经做了正确的事情。 ( 也应该回答它应该做些什么的问题,例如[[[], []], [], [[]]],但也要确保你也考虑过这个案例。)

答案 2 :(得分:0)

因此,基本上,您所指的数据结构是k-ary树,也称为n-ary树,具有任意分支。这是确定最大值的代码。具有任意分支的n-ary树的深度。

def maxdepth(tree):
    if isleaf(tree):
        return 1
    maximum = 0
    for child in children(tree):
        depth = maxdepth(child)
        if depth > maximum:
            maximum = depth
    return maximum + 1

您可以使用不同的测试输入here查看代码。