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



15 Answers

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

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

Yes: if not seq:
     if seq:

No:  if len(seq):
     if not len(seq):
python list判斷

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

a = []

如何檢查a是否為空?




其他人似乎將這個問題概括為僅僅是列表,所以我想我會為很多人可能會使用的不同類型的序列添加一個警告,特別是因為這是“python test empty array”的第一個google點擊。

其他方法不適用於numpy數組

你需要小心numpy數組,因為對於numpy數組,其他適用於list或其他標準容器的方法都會失敗。 我在下面解釋原因,但簡而言之, 首選方法是使用size

“pythonic”方式不起作用:第1部分

“pythonic”方式因numpy數組而失敗,因為numpy嘗試將數組轉換為bool數組,並且if x嘗試同時為某種聚合真值計算所有這些bool s。 但這沒有任何意義,所以你得到一個ValueError

>>> x = numpy.array([0,1])
>>> if x: print("x")
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

“pythonic”方式不起作用:第2部分

但至少上面的情況告訴你它失敗了。 如果碰巧有一個只有一個元素的numpy數組,那麼if語句將“起作用”,因為你沒有得到錯誤。 但是,如果那個元素碰巧是0 (或0.0false ,...),則if語句將錯誤地導致false

>>> x = numpy.array([0,])
>>> if x: print("x")
... else: print("No x")
No x

但顯然x存在並且不是空的! 這個結果不是你想要的。

使用len會產生意想不到的結果

例如,

len( numpy.zeros((1,0)) )

返回1,即使數組元素為零。

numpythonic方式

正如scipy FAQ中所解釋的那樣 ,在你知道你有一個numpy數組的所有情況下,正確的方法是使用if x.size

>>> x = numpy.array([0,1])
>>> if x.size: print("x")
x

>>> x = numpy.array([0,])
>>> if x.size: print("x")
... else: print("No x")
x

>>> x = numpy.zeros((1,0))
>>> if x.size: print("x")
... else: print("No x")
No x

如果您不確定它是否是list ,numpy數組或其他內容,您可以將此方法與@dubiousjim給出的答案結合起來,以確保為每種類型使用正確的測試。 不是很“pythonic”,但事實證明numpy至少在這個意義上有意破壞了pythonicity。

如果你需要做的不僅僅是檢查輸入是否為空,並且你正在使用索引或數學運算等其他numpy功能,那麼強制輸入成為一個numpy數組可能更有效(當然也更常見)。 快速執行此操作有一些很好的功能 - 最重要的是numpy.asarray 。 這會接受您的輸入,如果它已經是數組則不執行任何操作,或者如果輸入是列表,元組等,則將輸入包裝到數組中,並可選擇將其轉換為您選擇的dtype 。 所以只要它可以很快,它確保你只是假設輸入是一個numpy數組。 我們通常只使用相同的名稱,因為轉換為數組不會使其回到當前scope

x = numpy.asarray(x, dtype=numpy.double)

這將使x.size檢查在我在此頁面上看到的所有情況下x.size正常工作。




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

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

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

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




我已經看到以下是首選:

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






Python對於空虛的處理非常統一。 鑑於以下內容:

a = []

.
.
.

if a:
   print("List is not empty.")
else:
   print("List is empty.")

您只需使用“if”語句檢查列表a,看它是否為空。 從我讀過和教過的內容來看,這是查看列表或元組是否為空的“Pythonic”方式。




從關於真值測試的documentation

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

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

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

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



我更喜歡以下內容:

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

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




另一種簡單的方法可能是

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



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

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

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

非常方便和有用。




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

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 ..

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




一種非正式的方法:

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



空列表的真值是,False而對於非空列表則是True




查看在Python交互式終端上執行的以下代碼。

 >>> 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 >>> 



Related