最近有個文章很紅: 神級 Coder 絕不犯的錯誤:為炫耀編出超短碼在python界引起了一陣討論,主旨是在說不要為了炫耀自己實力寫出超級精簡,但是很難維護,別人很難懂的程式碼。這個觀念不是不對,但是引用了錯誤的例子而遭到"熱烈"的討論。
原文說想用python寫一隻計算漢明距離的公式,規則如下● abcde 與 abcde 之間的漢明距離為 0
● abcde與edcba之間的漢明距離為 4
● abc 與 abcde之間的漢明距離為 2
接著舉了兩個例子:
範例一:
範例二:
作者覺得第二個範例比較好,因為比較清楚易懂。
但是看推文可以發現一堆python人跳出來說,第一種寫法才是符合python邏輯的做法。對於不了解python的人可能看不懂範例一到底在幹嘛,以下將演示一下範例一裡面做了哪些事情。
1. map:
map 一般的用法是將map中的function套用在每個元素上,但是這邊用了一個特殊用法:如果有個None的參數,則會產生兩兩組合的tuple(https://docs.python.org/2/library/functions.html#map)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
map(None, 'abd', 'aberf') | |
#[('a', 'a'), ('b', 'b'), ('d', 'e'), (None, 'r'), (None, 'f')] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[(x,y) for x, y in map(None, 'abd', 'aberf')] | |
#[('a', 'a'), ('b', 'b'), ('d', 'e'), (None, 'r'), (None, 'f')] |
這是可能不容易注意到的地方,在python中boolean可以轉成int
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
print int(1 != 2), (1 != 2) | |
#1 True | |
print int(1 != 1), (1 != 1) | |
#0 False |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[int(x != y) for x, y in map(None, 'abd', 'aberf')] | |
#[0, 0, 1, 1, 1] |
這行程式之所以優美,在於充分使用了python的語言特性。讀懂一行程式,也就認識了python三個重要特性。
其實我也贊成第二種寫法,原因也是因為容易看得懂。
回覆刪除Python可以簡化迴圈的特性是出了名的優勢,這是一種語法糖(Syntactic sugar),讓人更便利使用Python來完成演算法。
可是我覺得寫程式的時候,邏輯比語法糖還要重要。語法糖的用意是封裝一些繁瑣常見的程式碼,但是不是拿來遮蔽邏輯的工具。
更何況,太過依賴語法糖,會使得人難以適應其他的程式語言。
Python很棒,但是在需要的時候用合適的程式語言來寫程式,我覺得這才是最棒的。
我舉R的例子好了。
刪除大家都知道R的for迴圈效率很差,都會用apply, sapply, lappay等功能
用for迴圈的確比較清楚,但是對於R USER來說sapply才是正確的用法。
例如我最近學的scala,那個語法糖才是多到爆炸(遠目)
val y = x.map(_+1).reduce(_+_).collect()
要把map改成for迴圈? 那殺了我比較快zzz
而且就熟悉scala的人來說,可能map還比for迴圈好懂