Python:如何检查嵌套列表是否本质上是空的?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1593564/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 22:39:23  来源:igfitidea点击:

Python: How to check if a nested list is essentially empty?

pythonlist

提问by Ashwin Nanjappa

Is there a Pythonic way to checkif a list(a nestedlist with elements & lists) is essentially empty? What I mean by empty here is that the list might have elements, but those are also empty lists.

是否有一个Python化的方式检查是否列表(一个嵌套的元素和清单列表)基本上是空的?我在这里所说的空是指列表可能有元素,但那些也是空列表。

The Pythonic way to check an empty list works only on a flat list:

检查空列表的 Pythonic 方法仅适用于平面列表:

alist = []
if not alist:
    print("Empty list!")

For example, all the following lists should be positive for emptiness:

例如,以下所有列表都应该为空:

alist = []
blist = [alist]               # [[]]
clist = [alist, alist, alist] # [[], [], []]
dlist = [blist]               # [[[]]]

采纳答案by Ashwin Nanjappa

I have combined the use of isinstance()by Ants Aasmaand all(map())by Stephan202, to form the following solution. all([])returns Trueand the function relies on this behaviour. I think it has the best of both and is better since it does not rely on the TypeErrorexception.

我已经联合使用isinstance()通过蚂蚁Aasmaall(map())Stephan202,以形成以下溶液。all([])返回True并且该函数依赖于这种行为。我认为它兼具两者的优点并且更好,因为它不依赖于TypeError异常。

def isListEmpty(inList):
    if isinstance(inList, list): # Is a list
        return all( map(isListEmpty, inList) )
    return False # Not a list

回答by Nahuel Brandan

Use the any()function. This returns Trueif any list within the list is not empty.

使用该any()功能。这将返回True如果列表中的任何列表不为空。

alist = [[],[]]
if not any(alist):
    print("Empty list!")

>> Empty list!

see: https://www.programiz.com/python-programming/methods/built-in/any

见:https: //www.programiz.com/python-programming/methods/built-in/any

回答by Stephan202

Simple code, works for any iterable object, not just lists:

简单的代码,适用于任何可迭代对象,而不仅仅是列表:

>>> def empty(seq):
...     try:
...         return all(map(empty, seq))
...     except TypeError:
...         return False
...
>>> empty([])
True
>>> empty([4])
False
>>> empty([[]])
True
>>> empty([[], []])
True
>>> empty([[], [8]])
False
>>> empty([[], (False for _ in range(0))])
True
>>> empty([[], (False for _ in range(1))])
False
>>> empty([[], (True for _ in range(1))])
False

This code makes the assumption that anything that can be iterated over will contain other elements, and should not be considered a leaf in the "tree". If an attempt to iterate over an object fails, then it is not a sequence, and hence certainly not an empty sequence (thus Falseis returned). Finally, this code makes use of the fact that allreturns Trueif its argument is an empty sequence.

此代码假设任何可以迭代的内容都将包含其他元素,并且不应将其视为“树”中的叶子。如果尝试迭代一个对象失败,那么它不是一个序列,因此肯定不是一个空序列(因此False被返回)。最后,此代码利用了如果其参数是空序列则all返回的事实True

回答by Ants Aasma

If you do not need to iterate through the lists, simpler is better, so something like this will work:

如果您不需要遍历列表,则越简单越好,因此可以使用以下方法:

def empty_tree(input_list):
    """Recursively iterate through values in nested lists."""
    for item in input_list:
        if not isinstance(item, list) or not empty_tree(item):
             return False
    return True

However, it would be good to separate the recursive iteration that you will most probably reuse elsewhere and checking that it returns no elements. This way if the mechanism of iteration changes you need to implement the change in one place. For instance when you need to support arbitrary nested iterables, or nested dicts.

但是,最好将您最有可能在其他地方重用的递归迭代分开并检查它是否不返回任何元素。这样,如果迭代机制发生变化,您需要在一个地方实现更改。例如,当您需要支持任意嵌套的可迭代对象或嵌套的字典时。

def flatten(input_list):
    """Recursively iterate through values in nested lists."""
    for item in input_list:
        if isinstance(item, list): # Use what ever nesting condition you need here
            for child_item in flatten(item):
                yield child_item
        else:
            yield item

def has_items(seq):
    """Checks if an iterator has any items."""
    return any(1 for _ in seq)

if not has_items(flatten(my_list)):
    pass

回答by Pierre Bourdon

I don't think there is an obvious way to do it in Python. My best guess would be to use a recursive function like this one :

我认为在 Python 中没有明显的方法可以做到这一点。我最好的猜测是使用这样的递归函数:

def empty(li):
    if li == []:
        return True
    else:
        return all((isinstance(sli, list) and empty(sli)) for sli in li)

Note that allonly comes with Python >= 2.5, and that it will not handle infinitely recursive lists (for example, a = []; a.append(a)).

请注意,all仅随 Python >= 2.5 一起提供,并且它不会处理无限递归列表(例如,a = []; a.append(a))。

回答by Anurag Uniyal

A simple recursive check would be enough, and return as early as possible, we assume it input is not a list or contains non-lists it is not empty

一个简单的递归检查就足够了,并尽可能早地返回,我们假设它输入不是列表或包含非列表它不为空

def isEmpty(alist):
    try:
        for a in alist:
            if not isEmpty(a):
                return False
    except:
        # we will reach here if alist is not a iterator/list
        return False

    return True

alist = []
blist = [alist]               # [[]]
clist = [alist, alist, alist] # [[], [], []]
dlist = [blist]               # [[[]]]
elist = [1, isEmpty, dlist]

if isEmpty(alist): 
    print "alist is empty"

if isEmpty(dlist): 
    print "dlist is empty"

if not isEmpty(elist): 
    print "elist is not empty"

You can further improve it to check for recursive list or no list objects, or may be empty dicts etc.

您可以进一步改进它以检查递归列表或无列表对象,或者可能是空字典等。

回答by Oreilles

def isEmpty(a):
    return all([isEmpty(b) for b in a]) if isinstance(a, list) else False

Simply.

简单地。