python - tuplas - Contando la profundidad o el nivel más profundo al que va una lista anidada
llenar una lista en python (10)
Amplitud primero, sin recursión, y también funciona con otros tipos de secuencia:
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)))
La misma idea, pero con mucho menos consumo de memoria:
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
A tiene un problema real (y un dolor de cabeza) con una tarea ...
Estoy en una clase de programación introductoria, y tengo que escribir una función que, dada una lista, devolverá la profundidad "máxima" a la que ... Por ejemplo: [1,2,3] devolverá 1, [ 1, [2,3]] devolverá 2 ...
He escrito este código (es lo mejor que pude obtener T_T)
def flat(l):
count=0
for item in l:
if isinstance(item,list):
count+= flat(item)
return count+1
Sin embargo, obviamente no funciona como debería, porque si hay listas que no cuentan para la profundidad máxima, aún aumenta el contador ...
Por ejemplo: cuando uso la función con [1,2, [3,4], 5, [6], 7] debería devolver 2, pero devuelve 3 ...
Cualquier idea o ayuda sería muy apreciada ^^ muchas gracias !! He estado luchando con esto por semanas ...
Aquí hay una forma de escribir la función.
depth = lambda L: isinstance(L, list) and max(map(depth, L))+1
Creo que la idea que te estás perdiendo es usar max()
La solución de @ John es excelente, pero para abordar los casos de listas vacías, como []
, [[]]
, es posible que deba hacer algo como esto
depth = lambda L: isinstance(L, list) and (max(map(depth, L)) + 1) if L else 1
Lo hice en una línea de python :)
disfrutar
def f(g,count=0): return count if not isinstance(g,list) else max([f(x,count+1) for x in g])
Manera abusiva: Di que tu lista se llama 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))])
Esto convierte su lista en una lista de corchetes de apertura y cierre, y luego encuentra el mayor número de corchetes de apertura que se producen antes de que se produzca el corchete de cierre correspondiente.
Primero reformulemos un poco sus requisitos.
La profundidad de una lista es uno más que la profundidad máxima de sus sub-listas.
Ahora, esto se puede traducir directamente al código:
def depth(l):
if isinstance(l, list):
return 1 + max(depth(item) for item in l)
else:
return 0
Una breve adición a lo que se ha dicho para que pueda manejar listas vacías también:
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
Una forma que no necesita módulos adicionales y tiene la misma velocidad, independientemente de la profundidad:
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))
Básicamente, lo que esto hace es convertir la lista en una cadena usando repr()
. Luego, para cada carácter en esta cadena igual a "(" o "[" aumenta el count
variable. Para los corchetes de cierre disminuye el count
. Luego devuelve el máximo que el count
ha alcanzado.
fácil con recursión
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
Extendí la respuesta de Hammar para cada iterable (cadenas deshabilitadas por defecto):
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