Estoy tratando de hacer una función que devuelva max de la lista anidada?

Escribí esto y está funcionando bien con todo, pero cuando tengo una lista vacía en una lista dada ( given_list=[[],1,2,3] ) dice que el índice está fuera de rango. ¿Alguna ayuda?

 def r_max (given_list): largest = given_list[0] while type(largest) == type([]): largest = largest[0] for element in given_list: if type(element) == type([]): max_of_elem = r_max(element) if largest < max_of_elem: largest = max_of_elem else: # element is not a list if largest < element: largest = element return largest 

Está asumiendo que given_list tiene al menos 1 elemento que es incorrecto. Para evitar un índice fuera de rango, puede agregar

 if (len(given_list) == 0) return None 

al comienzo de tu función.

ese error indica que su índice está fuera de rango, lo cual es el caso con el primer elemento de su ejemplo. La solución no es iterar sobre listas de longitud cero:

 def r_max (given_list): largest = given_list[0] while type(largest) == type([]): largest = largest[0] for element in given_list: if type(element) == type([]): # If the list is empty, skip if(len(elemnt) == 0) next max_of_elem = r_max(element) if largest < max_of_elem: largest = max_of_elem else: # element is not a list if largest < element: largest = element return larges 

mientras está en ello, es posible que desee assert len(given_list)>0 o algo equivalente.

Si el anidamiento es arbitrariamente profundo, primero necesita recursión para desenmarañarlo:

 def items(x): if isinstance(x, list): for it in x: for y in items(it): yield y else: yield x 

Ahora, max(items(whatever)) funcionará bien.

En los últimos lanzamientos de Python 3 puede hacer esto más elegante cambiando

  for it in x: for y in items(x): yield y 

dentro:

  for it in x: yield from it 

Si está seguro de que solo habrá un nivel de anidación allí, podría hacer algo como

 def r_max(lst): new_lst = [] for i in lst: try: new_lst.extend(i) except TypeError: new_lst + [i] return max(new_lst) 

Pero no estoy enamorado de esa solución, pero podría inspirarte a encontrar algo mejor.

Dos cosas que me gustaría destacar sobre esta solución, en contraste con la suya:

  1. Todo el control de tipo que estás haciendo ( type(largest) == type([]) , etc.) no se considera Python idiomático. Funciona, pero uno de los puntos clave de Python es que promueve la tipificación de pato / EAFP , lo que significa que debería preocuparse más por lo que puede hacer un objeto (en oposición a qué tipo es), y que solo debe intentarlo. Rellena y recupera en lugar de averiguar si puedes hacerlo.
  2. Python tiene una función perfectamente buena de “encontrar el número más grande en una lista” – max . Si puede hacer que su entrada sea una lista no anidada, entonces max hace el rest por usted.

Esto encontrará el máximo en una lista que contiene listas anidadas e ignora las instancias de cadena.

 A = [2, 4, 6, 8, [[11, 585, "tu"], 100, [9, 7]], 5, 3, "ccc", 1] def M(L): # If list is empty, return nothing if len(L) == 0: return # If the list size is one, it could be one element or a list if len(L) == 1: # If it's a list, get the maximum out of it if isinstance(L[0], list): return M(L[0]) # If it's a string, ignore it if isinstance(L[0], str): return # Else return the value else: return L[0] # If the list has more elements, find the maximum else: return max(M(L[:1]), M(L[1:])) print A print M(A) 

BLOG de Padmal

Supongo que el elemento máximo de una lista vacía es infinito negativo.

Este supuesto tratará los casos como [], [1,2, [], 5,4, []]

 def find_max(L): if len(L) == 0: return float("-inf") elif len(L) == 1: if isinstance(L[0], list): return find_max(L[0]) else: return L[0] elif len(L) == 2: if isinstance(L[0], list): firstMax = find_max(L[0]) else: firstMax = L[0] if isinstance(L[1], list): lastMax = find_max(L[1]) else: lastMax = L[1] if firstMax > lastMax: return firstMax else: return lastMax else: if isinstance(L[0], list): firstMax = find_max(L[0]) lastMax = find_max(L[1:]) if firstMax > lastMax: return firstMax else: return lastMax else: lastMax = find_max(L[1:]) if L[0] > lastMax: return L[0] else: return lastMax