前言
今天隨手翻 stackoverflow,看到問題叫 How do I check if a list is empty? 一看這個問題,不難猜到到這是一個剛學 Python 的人提問的,因為這個問題實在是太基礎了,那么如何判斷呢?
寫法
寫法一
a = []
if len(a) == 0:
print("empty list")
寫法二
a = []
if not a:
print("empty list")
這兩種寫法都很常見。那么問題來了,第一種寫法用列表長度去判斷列表為空可以理解,那么第二種寫法直接去判斷,這是怎么判斷出來的呢?
if
為了解決這個問題,我們首先需要重新認識一下 if。關於 if 是用來做條件執行的這一點,大家肯定都知道。
這里我們順便看一下官方文檔的描述
The if statement is used for conditional execution:
if_stmt ::= "if" expression ":" suite
("elif" expression ":" suite)*
["else" ":" suite]
It selects exactly one of the suites by evaluating the expressions one by one until one is found to be true; then that suite is executed
注意上面加粗的地方 true, 很明顯 if 后面表達式預期值應該為 true 或者 false,也就是說寫法二中的 a 最后的值也應該為 true 或者 false,那是怎么做到的呢?
bool
最簡單的辦法去判斷 a 是否為 true 或者 false,就是使用內置函數 bool()
>>> a = []
>>> bool(a)
False
正常調用 bool() 這個函數的時候,會去調用變量的內建方法 __bool__(),那如何看一個變量有哪些內建方法呢?在上一篇__name__是什么提到了一個的函數 dir(),在這里也同樣可以用來使用
>>> dir(a)
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
似乎沒有看到 __bool__() 這個函數,那怎么辦呢? 不用着急,官方文檔中還說了這樣的一句話
When this method (
__bool__()) is not defined,__len__()is called, if it is defined, and the object is considered true if its result is nonzero. If a class defines neither__len__()nor__bool__(), all its instances are considered true.
當一個變量沒有定義 __bool__ 的時候,不用着急,如果定義了 __len() 這個函數也是可以的,當長度不為 0 的時候則為 true。
總結
之所以在寫法二中可以用 if 直接判斷列表 a 是否為空,是因為對於 list 來說,它沒有內建方法 __bool__(),而有內建方法 __len__(),最后通過判斷 list 長度是否為 0 來得出 true 或者 false 的,一旦為空,則判斷結果為 false
