【Python】關於如何判斷一個list是否為空的思考

前言

今天隨手翻 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