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
Python: How to check if a nested list is essentially empty?
提问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 True
and the function relies on this behaviour. I think it has the best of both and is better since it does not rely on the TypeError
exception.
我已经联合使用isinstance()
通过蚂蚁Aasma和all(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 True
if 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 False
is returned). Finally, this code makes use of the fact that all
returns True
if 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 all
only 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.
简单地。