问题描述
i = [[1,2,3,[]],[],[4,5,7]]
我想删除所有的空列表:
[[1,3],7]]
我该怎么做?
这是我的代码:
res = [ele for ele in i if ele != []]
解决方法
使用递归函数从列表中删除空列表。
使用递归,您可以删除任何深度的空列表:
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,[]],[],[4,5,7]]
print(f"before-->{a}")
remove_nested_list(a)
print(f"after-->{a}")
输出:
before-->[[1,7]]
after-->[[1,0],7]]
,
从任意嵌套的列表中删除空列表。我们可以在这里使用递归。 这是一个简单的方法。我们需要遍历列表并检查元素是否为空列表。如果是,那么我们不会将其添加到最终列表中。如果不是空列表,我们重复上述过程。
def remove_empty(lst):
return (
[remove_empty(i) for i in lst if i!=[]]
if isinstance(lst,list)
else lst
)
输出:
i = [[1,7]]
print(remove_empty(i))
# [[1,3],7]]
# Example taken from iGian's answer
ii = [[1,7,[8,9,[10,11,[]]]]]
print(remove_empty(ii))
# [[1,11]]]]
要检查对象是否可迭代,我们使用 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
现在,您可以将 isinstance(lst,list)
替换为 isinstance(lst,Iterable)
以从每个迭代中过滤掉空列表,即 []
。
编辑:
@Teepeemm 指出了所有答案都遗漏的绝妙案例。
为了解决这个问题,我们需要两个递归函数,一个用于检查它是否为空嵌套列表,第二个用于删除空嵌套列表
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,[[]]]]
remove_empty(i)
# [[1,3]]
remove_nested_list(i) # Muhammad Safwan's answer
print(i) # [[1,[]]]
ii = [[1,[[],[[[[],[]]]]]]]
remove_empty(ii)
# [[1,3]]
remove_nested_list(ii) # Muhammad Safwan's answer
print(ii) # [[1,[[[[]]]]]]
,
我会使用一些不会改变原始列表的方法。
第一个简单地删除列表中的所有空列表,而不是嵌套的:
def remove_empty_lists(lst):
return [ e for e in lst if not (isinstance(e,list) and len(e)==0) ]
第二种方法只是以递归方式使用前者:
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 ]
所以,在提交的案例中:
i = [[1,7]]
deep_remove_empty_lists(i)
#=> [[1,7]]
或者在最深的嵌套情况下:
ii = [[1,[]]]]]
deep_remove_empty_lists(ii)
#=> [[1,11]]]]
,
您可以使用列表理解(实际上是嵌套理解):
i = [[1,7]]
res = [[sub_item for sub_item in item if sub_item != []] for item in i if item != []]
print(res)
我们检查空列表两次,一次使用 i
检查 if item != []
中的容器列表,另一次使用 if sub_item != []
检查这些容器内的单个元素。
如果嵌套总是两层深,即在你的问题中,一个干净的方法是:
>>> 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,7]]
处理像 []
这样的列表:
>>> i
[[1,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,7]]
,
如果您需要能够处理任意深度嵌套的列表,并且还想删除例如[[]]
或 [[],[]]]
或其他仅包含空列表(仅包含列表)的列表,这是一个简单的递归解决方案:
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,[[]]],[8]]]))
此解决方案与迄今为止发布的大多数(全部?)其他递归解决方案之间的主要区别在于,它首先递归地简化它遇到的任何子列表,然后然后跳过任何简化后为空的子列表。这使它也可以跳过 [[]]
之类的子列表。
(但是请注意,如果给定一个列表,该函数仍将始终返回一个列表,即使该列表可能为空。例如,simplify([[],[[]]])
仍将返回 []
而不是,比如说,None
。如果你想对简化后顶级列表为空的情况进行一些特殊处理,你需要单独检查。但至少在通过上面的函数运行列表之后,您可以使用例如 if simplified_list == []:
来检查这种情况。)
简单的递归解决方案
a = [[1,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)
输出:
[[1,7]]
,
只有在另一个列表中最多有一个列表时,它才会起作用。 [1,[1,2],3]
随着更多列表相互嵌套,您只需添加更多循环。
a = [[1,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)
这就是我得到的结果:
list before: [[1,7]]
list after: [[1,7]]
,
您还可以通过过滤“无值”来删除空列表。
试试:
i = filter(None,i)
,从列表中删除空列表
我们可以使用列表理解方法来解决这个问题。
你可以参考下面的代码
# Initialize list =>
list_1 = [11,20,12,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))
输出:
原始列表:[11,[ ],23]
删除空列表后的列表:[11,23]