2014年12月9日 星期二

[Python]神級 Coder 絕不犯的錯誤:為炫耀編出超短碼(疑?)


        最近有個文章很紅: 神級 Coder 絕不犯的錯誤:為炫耀編出超短碼在python界引起了一陣討論,主旨是在說不要為了炫耀自己實力寫出超級精簡,但是很難維護,別人很難懂的程式碼。這個觀念不是不對,但是引用了錯誤的例子而遭到"熱烈"的討論。
        原文說想用python寫一隻計算漢明距離的公式,規則如下
● abcde 與 abcde 之間的漢明距離為 0
● abcdeedcba之間的漢明距離為 4
● abc 與 abcde之間的漢明距離為 2
接著舉了兩個例子:
範例一:

範例二:

作者覺得第二個範例比較好,因為比較清楚易懂。
但是看推文可以發現一堆python人跳出來說,第一種寫法才是符合python邏輯的做法。對於不了解python的人可能看不懂範例一到底在幹嘛,以下將演示一下範例一裡面做了哪些事情。

1. map:
map 一般的用法是將map中的function套用在每個元素上,但是這邊用了一個特殊用法:如果有個None的參數,則會產生兩兩組合的tuple(https://docs.python.org/2/library/functions.html#map)

2. list comprehensive
3.True = 1,False = 0
這是可能不容易注意到的地方,在python中boolean可以轉成int

所以sum函式裡的東西會變成這樣

最後用Sum把比對不符(=1)的值加總,也就成了漢明距離。

這行程式之所以優美,在於充分使用了python的語言特性。讀懂一行程式,也就認識了python三個重要特性。



2 則留言:

  1. 其實我也贊成第二種寫法,原因也是因為容易看得懂。

    Python可以簡化迴圈的特性是出了名的優勢,這是一種語法糖(Syntactic sugar),讓人更便利使用Python來完成演算法。
    可是我覺得寫程式的時候,邏輯比語法糖還要重要。語法糖的用意是封裝一些繁瑣常見的程式碼,但是不是拿來遮蔽邏輯的工具。

    更何況,太過依賴語法糖,會使得人難以適應其他的程式語言。
    Python很棒,但是在需要的時候用合適的程式語言來寫程式,我覺得這才是最棒的。

    回覆刪除
    回覆
    1. 我舉R的例子好了。
      大家都知道R的for迴圈效率很差,都會用apply, sapply, lappay等功能
      用for迴圈的確比較清楚,但是對於R USER來說sapply才是正確的用法。

      例如我最近學的scala,那個語法糖才是多到爆炸(遠目)
      val y = x.map(_+1).reduce(_+_).collect()
      要把map改成for迴圈? 那殺了我比較快zzz
      而且就熟悉scala的人來說,可能map還比for迴圈好懂

      刪除