耐人尋味的 for...else...語句
老婆給當程式設計師的老公打電話:“下班順路買一斤包子帶回來,如果看到賣西瓜的,買一個。”當晚,程式設計師老公手捧一個包子進了家門……老婆怒道:“你怎麼就買了一個包子?”老公答曰:“因為看到了賣西瓜的。”
程式設計師買西瓜的笑話可能大部分讀者都知道,今天寫的這篇文章和這個笑話有一定的關係。
任何程式語言都提供了 if...else... 語句,表示如果(if)滿足條件就做某件事,否則(else)就做另外一件事:
if a==b: print("true") else: print("false")
然而,在 Python 中 else 不僅可以和 if 搭配使用,還有另一種特有的句法是 for…else …,除此之外,它還可以和 while、try…except 組合使用,例如:
for i in range(3): print(i) else: print("end") >>> 0 1 2 end
但是,你會發現 for…else… 與 if…else… 表現得不一樣,按照以往經驗來說,執行了 for 語句塊中的程式碼就不執行 else 裡面的,反之亦然。
然而,我們看到的卻恰恰相反,for 迴圈結束之後接著又執行了 else 語句塊,這就有點意思了,if … else … 翻譯成白話就是 如果…否則…,而 for…else… 翻譯成白話成了 直到… 然後 …,為什麼不把它寫成 for…then… 的句式呢?這不更好理解嗎?
另外,即使 for 迴圈遍歷的是一個空列表也會執行 else 語句塊。
for i in []: print(i) else: print("end") >>> end
繼續探索,如果我們用 break
提前終止 for 迴圈,會發生什麼?
for i in range(3): print(i) if i % 2 == 0: break else: print("end") >>> 0
迴圈遇到 break 退出後,整個語句就結束,else 語句塊也不執行了。
綜上,我們可以得出這樣一個結論,只有當迴圈裡沒有遇到 break 時,else 塊才會執行。此刻,你應該明白了,真正和 else 搭配使用的是 for 迴圈中的 break,break ... else ... 才是兩個互斥的條件
Python 之父為什麼要搞出這樣的一種語法糖出來呢?這是我們常人沒法理解的。不過「python之禪」告訴了我們答案: "Although that way may not be obvious at first unless you're Dutch."。
在平時的開發中真的很少有 for...else... 的應用場景,不過,像下面這種場景用 for else 還真是一種 pythonic 的用法。
當你用 for 迴圈迭代查詢列表的中的某個元素時,如果找到了就立刻退出迴圈,如果迭代完了列表還沒找到需要以另外一種形式(比如異常)的方式通知呼叫者時,用 for...else... 無疑是最好的選擇。
# https://stackoverflow.com/a/9980752/1392860 for i in mylist: if i == target: break process(i) else: raise ValueError("List argument missing terminal flag.")
如果不用 for...else... , 那麼還需要專門建立一個臨時標記變數來標記是否已經找到了
found = False for i in mylist: if i == target: found = True break process(i) if not found: raise ValueError("List argument missing terminal flag.")
當你想在房間裡找某樣東西時,只要在任意位置找到了,就停止繼續搜查工作。但如果把整個房間都翻遍了,還沒找到我們想要的東西時,需要告訴人家,很抱歉,這兒沒有你要找的東西。遇到這樣的情況時就用 for ... else ,除此之外,恐怕只會引起誤操作。
參考連結:https://stackoverflow.com/questions/9979970/why-does-python-use-else-after-for-and-while-loops/9980752#9980752
關注公眾號「Python之禪」(id:vttalk)獲取最新文章