I have a list:
i = [[1,2,3,[]],[],[],[],[4,5,[],7]]
I want to remove all the empty list:
[[1,2,3],[4,5,7]]
How can I do this?
Here is my code:
res = [ele for ele in i if ele != []]
It will only work as long as you have up to one list within another list. [1,2,[1,2],3]
With more lists nested in each other you will just have to add more loops.
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)
That's what I get as a result:
list before: [[1, 2, 3, 0, []], [], [], [], [4, 5, [], 7]]
list after: [[1, 2, 3, 0], [4, 5, 7]]
Use a recursive function to remove the empty list from a list.
Using recursion you can remove an empty list to any depth:
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]]
You can use list comprehension(actually nested comprehension) :
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)
We check for empty lists two times, one for container lists in i
with if item != []
and one for individual elements inside those containers with if sub_item != []
.
You can also remove empty list by filtering for "None values".
try:
i = filter(None, i)
I would use a couple of methods that doesn't mutate the original list.
The first simply removes all the empty lists in a list, not the nested:
def remove_empty_lists(lst):
return [ e for e in lst if not (isinstance(e, list) and len(e)==0) ]
The second method just uses the former in a recursive way:
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 ]
So, in the submitted case:
i = [[1,2,3,[]],[],[],[],[4,5,[],7]]
deep_remove_empty_lists(i)
#=> [[1, 2, 3], [4, 5, 7]]
Or in a deepest nesting case:
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]]]]
If the nesting always two levels deep, i.e. as in your question, a clean way would be:
>>> 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]]
To tackle a list like []
:
>>> 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]]
To remove empty lists from the arbitrarily nested list. We can use recursion here. Here's a simple way to do it. We need to iterate through the list and check if an element is an empty list. If yes, then we don't add it to the final list. If it's not an empty list we repeat the above process.
def remove_empty(lst):
return (
[remove_empty(i) for i in lst if i!=[]]
if isinstance(lst, list)
else lst
)
Output:
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]]]]
To check if an object is iterable we use 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
Now, you can replace isinstance(lst, list)
with isinstance(lst, Iterable)
to filter out empty list i.e []
from every iterable.
@Teepeemm pointed out a wonderful corner-case which all the answers missed.
To solve it we need two recursive functions one for checking if it's an empty nested list and the second one for remove empty nested lists
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, [[[[]]]]]]
If you need to be able to handle lists nested arbitrarily deeply, and also want to remove e.g. [[]]
or [[], [[], []]]
or other lists containing nothing but (lists containing nothing but) empty lists, here's a simple recursive solution:
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]]]))
The main difference between this solution and most (all?) of the other recursive ones posted so far is that it first recursively simplifies any sublists it encounters and then skips any sublists that are empty after simplification. This is what allows it to also skip sublists like [[]]
.
(Note, however, that this function will still always return a list if given a list, even if that list may be empty. For example, simplify([[], [[]]])
will still return []
instead of, say, None
. If you want to have some special handling for the case where the top-level list is empty after simplification, you'll need to check for that separately. But at least after running the list through the function above, you can check for that case just using e.g. if simplified_list == []:
.)
We can solve this using list comprehension method.
You can refer the below code for the same
# 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))
Output:
Original List: [11, 20, 5, [ ], 7, 12, 3, [ ], [ ], 23]
list after empty list removed: [11, 20, 5, 7, 12, 3, 23]
simple recursive solution
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)
Output:
[[1, 2, 3], [4, 5, 7]]