[Python]判斷序列是否為空的正確姿勢


本篇文章起源於StackOverflow上一個熱度非常高的問題:

我該如何判斷一個Python列表是否為空?

@Ray Vega (提問者)

舉例說明,現在我得到了如下代碼:

a = []

我如何該檢查 a 是否為空?

面對這個問題,各路高手給出了不盡相同的回答。


最高票答案十分簡潔:

@Patrick (答題者)

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

利用空列表的隱式布爾值是一個非常Pythonic的方式。


排名第二的答案與第一觀點相同,並以PEP 8作為依據,說明不僅是列表,Python中的內置序列類型都有推薦的做法:

@Harley Holcombe (答題者)

PEP 8 風格指南 給出了推薦的Pythonic的方法(其中Yes 表示推薦No表示不推薦):

對序列數據類型(字符串,列表,元組),利用空列表隱式為False的事實

Yes: if not seq:
  if seq:

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

然而,排名第三的答案給出了不同的看法:

我更推薦顯式的方法:

if len(li) == 0:
 print('the list is empty')

這種方式明確聲明了li是一個序列類型的變量,並且我們是在檢查它的長度。而if not li的問題在於,它會給我li是一個布爾類型變量的印象。


那么,判斷列表(序列)是否為空的正確姿勢到底是什么呢?這貌似只是一個編碼風格的問題,但我們分別從兩類不同看法的出發點挖掘更深層次的原因,可以讓自己更明確地選擇適合自己的風格。


什么是PEP 8

PEP,全稱Python Enhancement Proposals (翻譯過來就是Python增強建議書),有興趣的讀者可以直接閱覽PEP原文PEP本質上是一份Python的官方文檔,給Python社區提供信息,或者描述Python的新特性或開發進展。而PEP 8是這個文檔庫中的一員,專門用於描述Python的編碼規范,這里規范是指官方推薦的,被認為是更符合Python設計哲學的各種實踐

同樣實現相同的功能,不同編程語言的傾向於使用不同的風格,這是因為每種語言都有自身的設計目的,而Python的設計目的非常明顯:優雅,簡單,可讀。正如PEP 20(另一份PEP)Python之禪中所說:

簡單優於復雜

於是,依據序列長度是否為0將序其隱式轉化為布爾值,成為Python實現中的特性之一,並成為官方推薦的判斷序列是否為空的Pythonic方式。

關於Python是如何做到序列類型乃至所有類型到布爾值的隱式轉化的,我會專門就此問題寫文討論,歡迎關注。


什么是動態類型

那么為什么還會有人提出明確使用看上去復雜的if len(li) == 0來判斷,並且還有很多人表示贊同呢?這其實來源於Python語言的動態類型特性。

關於什么是動態類型,我也會另外專門討論,在這里,我們只需闡明,動態類型帶來了一個弊端,我們無法對變量在程序中某一位置的類型進行准確判斷。在閱讀Python代碼的過程中,我們可能最為頭痛的問題就是:這里這個變量是什么(類型)???唯一留給我們的線索也許只有變量名了。而在靜態類型語言,如Java中,一個變量的類型從其聲明時是確定的,在程序中不會發生改變。

回到我們的問題,if not li,看到這段代碼的程序猿可能會疑惑,這里的li變量是什么,是一個布爾類型?還是一個整型?這里的測試是在干什么?而if len(li) == 0可以很大程度上進行提示:這大抵是個容器性質的變量,我們在做的大抵是判斷其元素數量是否為0.


總結

討論到這里,我們仍然只能說,Python中如何判斷一個列表是否為空,是一個與風格和習慣有關的問題,但是深入探究我們發現,風格和習慣不是目的,而是手段,代碼最終是服務於編碼者和閱讀者的,拋開性能問題,只從可讀性出發,你希望閱讀這份代碼的人接受到的是什么,是簡單優雅,還是信息提示,這才是比所謂Pythonic更值得思考的問題。


獲取最新文章更新,歡迎關注我的公眾號: StackOverflow Daily


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM