Is there a Pythonic way to check if a list (a nested list with elements & lists) is essentially empty? What I mean by
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.
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 :
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)
).
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.
I have combined the use of isinstance()
by Ants Aasma and 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.
def isListEmpty(inList):
if isinstance(inList, list): # Is a list
return all( map(isListEmpty, inList) )
return False # Not a list
Use the any()
function. This returns True
if any list within the list is not empty.
alist = [[],[]]
if not any(alist):
print("Empty list!")
>> Empty list!
see: https://www.programiz.com/python-programming/methods/built-in/any
def isEmpty(a):
return all([isEmpty(b) for b in a]) if isinstance(a, list) else False
Simply.