可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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...
回答1:
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
回答2:
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()
回答3:
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
回答4:
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
回答5:
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])
回答6:
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.
回答7:
A way that does not need any additional modules and has the same speed, no mater 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.
回答8:
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
回答9:
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
回答10:
@John's solution is excellent, but to address the empty list cases, like []
, [[]]
, you may need to do something like this
depth = lambda L: isinstance(L, list) and (max(map(depth, L)) + 1) if L else 1