删除列表中存在的任何空列表 输出:

问题描述

我有一个清单:

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]]]))

Try it online!

此解决方案与迄今为止发布的大多数(全部?)其他递归解决方案之间的主要区别在于,它首先递归地简化它遇到的任何子列表,然后然后跳过任何简化后为空的子列表。这使它也可以跳过 [[]] 之类的子列表。

(但是请注意,如果给定一个列表,该函数仍将始终返回一个列表,即使该列表可能为空。例如,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]

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...