本篇文章起源於StackOverflow上一個熱度很是高的問題:python
@Ray Vega (提問者)編程語言
舉例說明,如今我獲得了以下代碼:性能
a = []我如何該檢查
a
是否爲空?測試
面對這個問題,各路高手給出了不盡相同的回答。編碼
最高票答案十分簡潔:翻譯
@Patrick (答題者)設計
if not a: print("List is empty")利用空列表的隱式布爾值是一個很是Pythonic的方式。code
排名第二的答案與第一觀點相同,並以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,全稱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