tengo una lista:
i = [[1,2,3,[]],[],[],[],[4,5,[],7]]
Quiero eliminar toda la lista vacía:
[[1,2,3],[4,5,7]]
¿Cómo puedo hacer esto?
Aquí está mi código:
res = [ele for ele in i if ele != []]
Solo funcionará mientras tenga una lista dentro de otra lista. [1,2,[1,2],3]
Con más listas anidadas entre sí, solo tendrá que agregar más bucles.
a = [[1, 2, 3, 0, []], [], [], [], [4, 5, [], 7]] print('list before:', a) while [] in a: for i in a: if i == []: a.remove(i) for i in a: for e in i: if e == []: i.remove(e) print('list after:', a)
Eso es lo que obtengo como resultado:
list before: [[1, 2, 3, 0, []], [], [], [], [4, 5, [], 7]] list after: [[1, 2, 3, 0], [4, 5, 7]]
Use una función recursiva para eliminar la lista vacía de una lista.
Usando la recursión puede eliminar una lista vacía a cualquier profundidad:
def remove_nested_list(listt): for index, value in enumerate(reversed(listt)): if isinstance(value, list) and value != []: remove_nested_list(value) elif isinstance(value, list) and len(value) == 0: listt.remove(value) a = [[1, 2, 3, 0, []], [], [], [], [4, 5, [], 7]] print(f"before-->{a}") remove_nested_list(a) print(f"after-->{a}")
before-->[[1, 2, 3, 0, []], [], [], [], [4, 5, [], 7]] after-->[[1, 2, 3, 0], [4, 5, 7]]
Puede usar la comprensión de listas (en realidad, comprensión anidada):
i = [[1, 2, 3, []], [], [], [], [4, 5, [], 7]] res = [[sub_item for sub_item in item if sub_item != []] for item in i if item != []] print(res)
Verificamos las listas vacías dos veces, una para las listas de contenedores en i
con if item != []
y otra para elementos individuales dentro de esos contenedores con if sub_item != []
.
También puede eliminar la lista vacía filtrando por "Ninguno de los valores".
tratar:
i = filtro(Ninguno, i)
Usaría un par de métodos que no mutan la lista original.
El primero simplemente elimina todas las listas vacías en una lista, no las anidadas:
def remove_empty_lists(lst): return [ e for e in lst if not (isinstance(e, list) and len(e)==0) ]
El segundo método solo usa el primero de forma recursiva:
def deep_remove_empty_lists(lst): lst = remove_empty_lists(lst) return [ deep_remove_empty_lists(e) if isinstance(e, list) else e for e in lst ]
Entonces, en el caso presentado:
i = [[1,2,3,[]],[],[],[],[4,5,[],7]] deep_remove_empty_lists(i) #=> [[1, 2, 3], [4, 5, 7]]
O en un caso de anidamiento más profundo:
ii = [[1,2,3,[]],[],[],[],[4,5,[],7,[8, 9, [], [10, 11, []]]]] deep_remove_empty_lists(ii) #=> [[1, 2, 3], [4, 5, 7, [8, 9, [10, 11]]]]
Si el anidamiento siempre tiene dos niveles de profundidad, es decir, como en su pregunta, una forma limpia sería:
>>> not_empty_list = lambda value: value != [] ## Above is equivalent to: # not_empty_list = [].__ne__ # not_empty_list = functools.partial(operator.ne, [])) >>> result = [ list(filter(not_empty_list, inner_list)) for inner_list in i if not_empty_list(inner_list) ] >>> result [[1, 2, 3], [4, 5, 7]]
Para abordar una lista como []
:
>>> i [[1, 2, 3, []], [], [], [], [4, 5, [], 7], [[]]] >>> result = [ list(filter(not_empty_list, inner_list)) for inner_list in i if not_empty_list(inner_list) ] >>> list(filter(not_empty_list, result)) [[1, 2, 3], [4, 5, 7]]
Para eliminar listas vacías de la lista anidada arbitrariamente. Podemos usar la recursividad aquí. Aquí hay una manera simple de hacerlo. Necesitamos iterar a través de la lista y verificar si un elemento es una lista vacía. Si es así, entonces no lo agregamos a la lista final. Si no es una lista vacía, repetimos el proceso anterior.
def remove_empty(lst): return ( [remove_empty(i) for i in lst if i!=[]] if isinstance(lst, list) else lst )
Producción:
i = [[1, 2, 3, []], [], [], [], [4, 5, [], 7]] print(remove_empty(i)) # [[1, 2, 3], [4, 5, 7]] # Example taken from iGian's answer ii = [[1, 2, 3, []], [], [], [], [4, 5, [], 7, [8, 9, [], [10, 11, []]]]] print(remove_empty(ii)) # [[1, 2, 3], [4, 5, 7, [8, 9, [10, 11]]]]
Para verificar si un objeto es iterable usamos collection.abc.iterable
from collections.abc import Iterable all( isinstance(i, Iterable) for i in ([], tuple(), set(), dict(), range(10), (_ for _ in range(10))) ) # True
Ahora, puede reemplazar isinstance(lst, list)
con isinstance(lst, Iterable)
para filtrar la lista vacía, es decir []
de cada iterable.
@Teepeemm señaló un maravilloso caso de esquina que todas las respuestas se perdieron.
Para resolverlo, necesitamos dos funciones recursivas, una para verificar si es una lista anidada vacía y la segunda para eliminar listas anidadas vacías.
def empty(lst): if lst == []: return True elif isinstance(lst, list): return all(empty(i) for i in lst) else: return False def remove_empty(lst): return ( [remove_empty(i) for i in lst if not empty(i)] if isinstance(lst, list) else lst ) i = [[1, 2, 3, [[]]]] remove_empty(i) # [[1, 2, 3]] remove_nested_list(i) # Muhammad Safwan's answer print(i) # [[1, 2, 3, []]] ii = [[1, 2, 3, [[], [[[[], []]]]]]] remove_empty(ii) # [[1, 2, 3]] remove_nested_list(ii) # Muhammad Safwan's answer print(ii) # [[1, 2, 3, [[[[]]]]]]
Si necesita poder manejar listas anidadas arbitrariamente profundamente y también desea eliminar, por ejemplo [[]]
o [[], [[], []]]
u otras listas que contienen nada más que (listas que contienen nada más que) listas vacías , aquí hay una solución recursiva simple:
def simplify(value): if isinstance(value, list): return [y for y in (simplify(x) for x in value) if y != []] else: return value print(simplify([[1,2,3,[]],[],[],[],[4,5,[],7],[[],[[]]],[[],[8]]]))
La principal diferencia entre esta solución y la mayoría (¿todas?) de las otras recursivas publicadas hasta ahora es que primero simplifica recursivamente las sublistas que encuentra y luego omite las sublistas que están vacías después de la simplificación. Esto es lo que le permite omitir también sublistas como [[]]
.
(Tenga en cuenta, sin embargo, que esta función siempre devolverá una lista si se le da una lista, incluso si esa lista puede estar vacía. Por ejemplo, simplify([[], [[]]])
todavía devolverá []
en lugar de, diga, None
. Si desea tener un manejo especial para el caso en que la lista de nivel superior está vacía después de la simplificación, deberá verificar eso por separado. Pero al menos después de ejecutar la lista a través de la función anterior, puede verifique ese caso simplemente usando, por ejemplo if simplified_list == []:
.)
Podemos resolver esto usando el método de comprensión de listas.
Puede consultar el siguiente código para el mismo
# Initialize list => list_1 = [11,20,5,[],7,12,3,[],[],23] # print list print("Original List: "+ str(list_1)) # remove empty list using list comprehension output = [ i for i in list_1 if i!=[] ] # print output print("list after empty list removed: " + str(output))
Producción:
Lista original: [11, 20, 5, [ ], 7, 12, 3, [ ], [ ], 23]
lista después de eliminar la lista vacía: [11, 20, 5, 7, 12, 3, 23]
solución recursiva simple
a = [[1,2,3,[]],[],[],[],[4,5,[],7]] def nested_check(alist): for item in alist[:]: if item == []: alist.remove(item) elif isinstance(item, list): nested_check(item) nested_check(a) print(a)
Producción:
[[1, 2, 3], [4, 5, 7]]