python - 空list - 如何檢查列表是否為空?




空list python (20)

檢查列表是否為空的最佳方法

例如,如果傳遞以下內容:

a = []

如何檢查a是否為空?

簡答:

將列表放在布爾上下文中(例如,使用ifwhile語句)。 如果它為空,它將測試False ,否則為True 。 例如:

if not a:                           # do this!
    print('a is an empty list')

上訴到權威

PEP 8是Python標準庫中Python代碼的官方Python風格指南,斷言:

對於序列,(字符串,列表,元組),請使用空序列為假的事實。

Yes: if not seq:
     if seq:

No: if len(seq):
    if not len(seq):

我們應該期望標準庫代碼應該盡可能高效和正確。 但為什麼會這樣,為什麼我們需要這個指導?

說明

我經常從經驗豐富的Python程序員那裡看到這樣的代碼:

if len(a) == 0:                     # Don't do this!
    print('a is an empty list')

懶惰語言的用戶可能會想要這樣做:

if a == []:                         # Don't do this!
    print('a is an empty list')

這些在各自的其他語言中是正確的。 這在Python中甚至在語義上也是正確的。

但我們認為它不是Pythonic,因為Python通過布爾強制直接在列表對象的接口中支持這些語義。

docs (並特別注意包含空列表, [] ):

默認情況下,對像被視為true,除非它的類定義了返回False__len__()方法或者在使用對象調用時返回零的__len__()方法。 以下是大多數被認為是錯誤的內置對象:

  • 定義為false的常量: NoneFalse
  • 任何數字類型的零: 0jDecimal(0)Fraction(0, 1)
  • 空序列和集合: ''()[]{}set()range(0)

和datamodel文檔:

object.__bool__(self)

被稱為實施真值測試和內置操作bool() ; 應該返回FalseTrue 。 如果未定義此方法,則調用__len__() (如果已定義__len__() ,如果對象的結果非零,則認為該對象為true。 如果類既未定義__len__()__bool__() ,則其所有實例都被視為true。

object.__len__(self)

被調用來實現內置函數len() 。 應返回對象的長度,整數> = 0.此外,未定義__bool__()方法且__len__()方法返回零的對像在布爾上下文中被視為false。

所以不是這樣的:

if len(a) == 0:                     # Don't do this!
    print('a is an empty list')

或這個:

if a == []:                     # Don't do this!
    print('a is an empty list')

做這個:

if not a:
    print('a is an empty list')

做Pythonic通常會在性能方面得到回報:

它有回報嗎? (注意,執行等效操作的時間越少越好:)

>>> import timeit
>>> min(timeit.repeat(lambda: len([]) == 0, repeat=100))
0.13775854044661884
>>> min(timeit.repeat(lambda: [] == [], repeat=100))
0.0984637276455409
>>> min(timeit.repeat(lambda: not [], repeat=100))
0.07878462291455435

對於比例,這是調用函數和構造並返回空列表的成本,您可以從上面使用的空白檢查的成本中減去:

>>> min(timeit.repeat(lambda: [], repeat=100))
0.07074015751817342

我們看到, 使用內置函數len檢查長度與0比較檢查空列表要比使用所記錄的語言的內置語法低得多。

為什麼?

對於len(a) == 0檢查:

首先Python必須檢查全局變量以查看len是否被遮蔽。

然後它必須調用函數,加載0 ,並在Python中進行相等比較(而不是使用C):

>>> import dis
>>> dis.dis(lambda: len([]) == 0)
  1           0 LOAD_GLOBAL              0 (len)
              2 BUILD_LIST               0
              4 CALL_FUNCTION            1
              6 LOAD_CONST               1 (0)
              8 COMPARE_OP               2 (==)
             10 RETURN_VALUE

對於[] == []它必須構建一個不必要的列表然後再次在Python的虛擬機中進行比較操作(而不是C)

>>> dis.dis(lambda: [] == [])
  1           0 BUILD_LIST               0
              2 BUILD_LIST               0
              4 COMPARE_OP               2 (==)
              6 RETURN_VALUE

“Pythonic”方式是一種更簡單,更快速的檢查,因為列表的長度緩存在對象實例頭中:

>>> dis.dis(lambda: not [])
  1           0 BUILD_LIST               0
              2 UNARY_NOT
              4 RETURN_VALUE

來自C源和文檔的證據

PyVarObject

這是PyObject的擴展,它添加了ob_size字段。 這僅用於具有一些長度概念的對象。 此類型通常不會出現在Python / C API中。 它對應於PyObject_VAR_HEAD宏擴展定義的字段。

Include/listobject.h的c源代碼:

typedef struct {
    PyObject_VAR_HEAD
    /* Vector of pointers to list elements.  list[0] is ob_item[0], etc. */
    PyObject **ob_item;

    /* ob_item contains space for 'allocated' elements.  The number
     * currently in use is ob_size.
     * Invariants:
     *     0 <= ob_size <= allocated
     *     len(list) == ob_size

我很喜歡研究這個,我花了很多時間來策劃我的答案。 如果您認為我要留下一些東西,請在評論中告訴我。

https://code.i-harness.com

例如,如果傳遞以下內容:

a = []

如何檢查a是否為空?


為什麼要檢查?

似乎沒有人質疑你是否需要首先測試清單。 因為您沒有提供額外的上下文,我可以想像您可能不需要首先進行此檢查,但不熟悉Python中的列表處理。

我認為最pythonic的方法是根本不檢查,而是只處理列表。 這樣,無論是空的還是滿的,它都會做正確的事情。

a = []

for item in a:
    <do something with item>

<rest of code>

這有利於處理a的任何內容,同時不需要對空白進行特定檢查。 如果a為空,則依賴塊將不會執行,解釋器將進入下一行。

如果你確實需要檢查數組是否空虛,那麼其他答案就足夠了。


pythonic的方法是從PEP 8樣式指南 (其中Yes表示“推薦”, No表示“不推薦”):

對於序列,(字符串,列表,元組),請使用空序列為假的事實。

Yes: if not seq:
     if seq:

No:  if len(seq):
     if not len(seq):


一種非正式的方法:

l = ["", False, 0, '', [], {}, ()]
if all(bool(x) for x in l):
    # do your stuff.

你甚至可以嘗試像這樣使用bool()

    a = [1,2,3];
    print bool(a); # it will return True
    a = [];
    print bool(a); # it will return False

我喜歡這種方式檢查清單是否為空。

非常方便和有用。


另一種簡單的方法可能是

a = []
if len(a) == 0:
  print("Empty")
else:
  print(" Not empty")

只需使用is_empty()或make函數: -

l = []
if l:
    # do your stuff.

它可以用於任何data_structure,如列表,元組,字典等等。通過這些,您可以使用just來多次調用它is_empty(any_structure)


如果要檢查列表是否為空;

def empty_list(lst):
    if len(lst) ==0:
        return false
    else:
        return all(bool(x) for x in l)

如果要查看天氣,列表中的所有值都為空。

if empty_list(lst):
    # do your stuff.

但是對於空列表,這將是True。

print('not empty' if a else 'empty')

現在你可以使用:

a.pop() if a else None

已經給出了很多答案,其中很多都很好。 我只想補充一下這張支票

not a

也會傳遞None和其他類型的空結構。 如果您確實想要檢查空列表,可以執行以下操作:

if isinstance(a, list) and len(a)==0:
    print("Received an empty list")

從python3開始你可以使用

 a = []
 try:
  print(a[-1])
 except IndexError:
  print("List is empty")

檢查列表是否為空

編輯:這也適用於python2.7 ..

我不確定為什麼會有這麼多複雜的答案。 它非常明確和直截了當


從關於真值測試的documentation

除此處列出的值之外的所有值都被視為True

  • None
  • False
  • 任何數字類型的零,例如, 0j
  • 任何空序列,例如''()[]
  • 任何空映射,例如{}
  • 用戶定義的類的實例,如果類定義__bool__()__len__()方法,則該方法返回整數零或bool值False

可以看出,空列表[]假的 ,所以對布爾值做的事情聽起來效率最高:

if not a:
    print('"a" is empty!')

我使用的一些方法:

if not a:
    print "list is empty"


if len(a) == 0:
    print "list is empty"

我已經看到以下是首選:

if not a:
    print("The list is empty or null")

我更喜歡以下內容:

if a == []:
   print "The list is empty."

可讀,您不必擔心調用像len()這樣的函數來遍歷變量。 雖然我不完全確定這樣的BigO符號是什麼......但是Python的速度如此之快,我懷疑它是否重要,除非a是巨大的。


我曾寫過:

if isinstance(a, (list, some, other, types, i, accept)) and not a:
    do_stuff

被評為-1。 我不確定是不是因為讀者反對這個策略或者認為答案沒有提供幫助。 我假裝它是後者,因為---無論什麼都算“pythonic” - 這是正確的策略。 除非你已經排除了,或者準備處理a例如False情況,否則你需要一個更嚴格的測試,而不僅僅是if not a: 。 你可以使用這樣的東西:

if isinstance(a, numpy.ndarray) and not a.size:
    do_stuff
elif isinstance(a, collections.Sized) and not a:
    do_stuff

第一個測試是對上面@ Mike的答案的回應。 第三行也可以替換為:

elif isinstance(a, (list, tuple)) and not a:

如果您只想接受特定類型(及其子類型)的實例,或者:

elif isinstance(a, (list, tuple)) and not len(a):

你可以在沒有顯式類型檢查的情況下離開,但前提是周圍的上下文已經確保a是你準備處理的類型的值,或者如果你確定你不准備處理的類型是要準備好處理錯誤(例如,如果你對未定義的值調用len ,則會出現TypeError )。 一般來說,“pythonic”慣例似乎是最後一種方式。 像鴨子一樣擠壓它,如果它不知道如何嘎嘎就讓它引發DuckError。 你仍然需要考慮你正在做什麼類型的假設,以及你不准備正確處理的案例是否真的會在正確的地方出錯。 Numpy數組是一個很好的例子,只是盲目地依賴於len或布爾類型轉換可能無法完全滿足您的期望。


簡單的方法是檢查長度是否等於零。

if len(a) == 0:
    print("a is empty")

您可以檢查數組的長度是否為零(或不是。)如果數組長度為零,則它為。嘗試以下方法:

>>> a = []
>>> if a:
...     print "List is not empty";
... else:
...     print "List is empty"
... 
List is empty
>>> 
>>> a = [1, 4, 9]
>>> if a:
...     print "List is not empty";
... else:
...     print "List is empty"
... 
List is not empty
>>> 

a == []

更實用一點:

def is_empty(any_structure):
    if any_structure:
        print('Structure is not empty.')
        return True
    else:
        print('Structure is empty.')
        return False  

def list_test (L):
    if   L is None  : print 'list is None'
    elif not L      : print 'list is empty'
    else: print 'list has %d elements' % len(L)

list_test(None)
list_test([])
list_test([1,2,3])

有時測試None和空虛是有好處的,因為它們是兩種不同的狀態。 上面的代碼產生以下輸出:

list is None 
list is empty 
list has 3 elements

雖然沒有什麼是虛假的,但None價值。 因此,如果您不想為None -ness分開測試,則不必這樣做。

def list_test2 (L):
    if not L      : print 'list is empty'
    else: print 'list has %d elements' % len(L)

list_test2(None)
list_test2([])
list_test2([1,2,3])

產生預期

list is empty
list is empty
list has 3 elements




is-empty