[英]Python: How to check if a nested list is essentially empty?
是否有一種 Pythonic 方法來檢查列表(帶有元素和列表的嵌套列表)是否本質上是空的? 我在這里所說的空是指列表可能有元素,但那些也是空列表。
檢查空列表的 Pythonic 方法僅適用於平面列表:
alist = []
if not alist:
print("Empty list!")
例如,以下所有列表都應該為空:
alist = []
blist = [alist] # [[]]
clist = [alist, alist, alist] # [[], [], []]
dlist = [blist] # [[[]]]
使用any()
函數。 如果列表中的任何列表不為空,則返回True
。
alist = [[],[]]
if not any(alist):
print("Empty list!")
>> Empty list!
見: https : //www.programiz.com/python-programming/methods/built-in/any
我結合了Ants Aasma的isinstance()
和Stephan202 的all(map())
的使用,形成了以下解決方案。 all([])
返回True
並且該函數依賴於這種行為。 我認為它兼具兩者的TypeError
並且更好,因為它不依賴於TypeError
異常。
def isListEmpty(inList):
if isinstance(inList, list): # Is a list
return all( map(isListEmpty, inList) )
return False # Not a list
簡單的代碼,適用於任何可迭代對象,而不僅僅是列表:
>>> 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
此代碼假設任何可以迭代的內容都將包含其他元素,不應將其視為“樹”中的葉子。 如果嘗試迭代對象失敗,則它不是序列,因此肯定不是空序列(因此返回False
)。 最后,這段代碼利用了這樣一個事實:如果其參數是空序列,則all
返回True
。
如果您不需要遍歷列表,則越簡單越好,因此可以使用以下方法:
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
但是,最好將您最有可能在其他地方重用的遞歸迭代分開並檢查它是否不返回任何元素。 這樣,如果迭代機制發生變化,您需要在一個地方實現更改。 例如,當您需要支持任意嵌套的可迭代對象或嵌套的字典時。
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
我認為在 Python 中沒有明顯的方法可以做到這一點。 我最好的猜測是使用這樣的遞歸函數:
def empty(li):
if li == []:
return True
else:
return all((isinstance(sli, list) and empty(sli)) for sli in li)
請注意, all
僅隨 Python >= 2.5 提供,並且不會處理無限遞歸列表(例如, a = []; a.append(a)
)。
一個簡單的遞歸檢查就足夠了,並盡可能早地返回,我們假設它輸入不是列表或包含非列表它不為空
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"
您可以進一步改進它以檢查遞歸列表或無列表對象,或者可能是空字典等。
def isEmpty(a):
return all(map(isEmpty,a)) if isinstance(a, list) else False
簡單地。
如果要檢查嵌套列表中是否沒有項目,可以使用這樣的深度優先搜索 (DFS) 遍歷方法
def is_list_empty(values: list):
if len(values) == 0:
return True
res = []
for val in values:
if isinstance(val, list):
res.append(is_list_empty(val))
else:
res.append(False)
return all(res)
v_list = [ [], [[1, 2], [], []], []]
is_list_empty(v_list) # False, as there are two times in it.
v_list = [ [], [[], [], []], []]
is_list_empty(v_list) # True, in fact ther is no item in it.
這類似於@AshwinNanjappa 的回答,但更容易理解。
可以通過使用len
函數檢查列表的長度是否等於零來檢查列表列表是否為空,然后使用any
給出True如果有任何True (至少有一個空子列表) , 如圖所示:
def empty(lis):
# True if there is an empty sublist
x = [True for i in lis if len(i) == 0]
# any function will return True if at least there is one True in x
if any(x):
print("There is an empty sublist!!")
else:
print("There is no any empty sublist")
lis = [[1,2,3],[3],[2]]
empty(lis)
# The output is: There is no any empty sublist
lis2 = [[1,2,3],[],[]]
empty(lis2)
# The output is: There is an empty sublist!!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.