计算嵌套列表的深度或最深级别

发布于 2024-11-08 17:43:06 字数 483 浏览 0 评论 0原文

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...

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

A have a real problem (and a headache) with an assignment...

I'm in an introductory programming class, and I have to write a function that, given a list, will return the "maximum" depth it goes to...
For example: [1,2,3] will return 1, [1,[2,3]] will return 2...

I've written this piece of code (it's the best I could get T_T)

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

However, It obviously doens't work like it should, because if there are lists that do not count for the maximum deepness, it still raises the counter...

For example: when I use the function with [1,2,[3,4],5,[6],7] it should return 2, but it returns 3...

Any ideas or help would be greatly appreciated ^^ thanks a lot!! I've been strugling with this for weeks now...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

够运 2024-11-15 17:43:06

这是编写函数的一种方法

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

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

Here is one way to write the function

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

I think the idea you are missing is to use max()

-黛色若梦 2024-11-15 17:43:06

让我们首先稍微重新表述一下您的要求。

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

现在,这可以直接转换为代码:

def depth(l):
    if isinstance(l, list):
        return 1 + max(depth(item) for item in l)
    else:
        return 0

Let's first rephrase your requirements slightly.

The depth of a list is one more than the maximum depth of its sub-lists.

Now, this can be translated directly to code:

def depth(l):
    if isinstance(l, list):
        return 1 + max(depth(item) for item in l)
    else:
        return 0
看春风乍起 2024-11-15 17:43:06

简单的递归

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

easy with recursion

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
情域 2024-11-15 17:43:06

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

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

Breadth-first, without recursion, and it also works with other sequence types:

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)))

The same idea, but with much less memory consumption:

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
烈酒灼喉 2024-11-15 17:43:06

用Python的一行代码完成的:)

享受

def f(g,count=0): return count if not isinstance(g,list) else max([f(x,count+1) for x in g])

Did it in one line of python :)

enjoy

def f(g,count=0): return count if not isinstance(g,list) else max([f(x,count+1) for x in g])
绿光 2024-11-15 17:43:06

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

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 已达到的最大值。

A way that does not need any additional modules and has the same speed, no matter what depth:

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))

Basically, what this does is convert the list to a string using repr(). Then for every character in this string equal to "(" or "[" it increases the variable count. for the closing brackets it decreases count. It then returns the maximum that count has reached.

紧拥背影 2024-11-15 17:43:06

辱骂方式:
假设您的列表名为 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))])

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

Abusive way:
Say your list is called 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))])

This converts your list to a list of opening and closing brackets, then finds the largest number of opening brackets that occur before the corresponding closing bracket occurs.

静谧 2024-11-15 17:43:06

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

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

奖励:此解决方案对空列表进行计数,并避免了遍历字符串的陷阱(假设您想对空列表进行计数)。

Let's stick with the original, fairly elegant solution and get it working using max. So many of the other solutions use lambda expressions or require external libraries. This one uses 'pure' python and keeps it simple.

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

Bonus: this solution counts empty lists and avoids the trap of traversing a string (provided you want to count empty lists).

忱杏 2024-11-15 17:43:06

Numpy中,您可以将数据结构转换为numpy数组并使用其库函数。 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
# -- Be dragons: --
f( [[1],[3,4]] ) # results in 1

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

In Numpy, you can convert the data structure to a numpy array and use its library functions. arr.shape gives length per layer, so we can len() the shape and get the depth of the structure:

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
# -- Be dragons: --
f( [[1],[3,4]] ) # results in 1

Numpy docs for shape: https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.shape.html

绮烟 2024-11-15 17:43:06

我为每个可迭代对象扩展了 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

I extended the hammar's answer for every iterable (strings disabled by default):

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
纵性 2024-11-15 17:43:06

如果您正在寻找快速修复方法

def getDepth(matrix):
    try:
        len(matrix)
        return getDepth(matrix[0]) + 1
    except:
        return 0

If you're looking for a quick fix

def getDepth(matrix):
    try:
        len(matrix)
        return getDepth(matrix[0]) + 1
    except:
        return 0
一江春梦 2024-11-15 17:43:06

对上述内容进行简短补充,以便它也可以处理空列表:

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

A short addition to what has been said so it can handle empty lists too:

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
ゃ人海孤独症 2024-11-15 17:43:06

您也可以仅使用 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)

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

you can also do it recursively using only 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)

this function is recursive and what it does is that it just goes to the maximum depth of your list counting how deep the list is, and when it climbs back up, it keeps only the biggest deepness registered among all nested lists.

我很坚强 2024-11-15 17:43:06

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

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

@John's solution is excellent, but to address the empty list cases, like [], [[]], or further nested lists, you may need to do something like this

depth = lambda L: isinstance(L, list) and (max(map(depth, L)) + 1) if str(L) else 1
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文