Python要你命三千

發表於2016-07-13

前言

文章有點標題黨,主要是分享一些Python好用的語法糖,用更少的程式碼實現同樣的功能,而且還很優雅。

兵器譜

  1. ifpython沒有三目運算子,我挺苦惱的,比如把兩個整數較大的那個複製給一個變數,有三目運算子的語言會這樣寫:

    後來發現Python的if語句可以寫成一行完成上述功能:
  2. with我們通常以如下形式操作檔案:

    每次這樣寫太繁瑣,來試試with的威力:

    程式碼更佳簡潔,並且不必呼叫f.close()方法。
    with利用了上下文管理協議,這玩意說起來太複雜,直接上程式碼。
    自定義一個支援上下文管理協議的類, 類中實現enter方法和exit方法。

    輸出:
  3. map大多數的for迴圈可以用map來代替,用法是:map(func,seq),對seq中的每個元素進行操作,具體什麼操作在func裡定義。
    我們以前是這麼寫for迴圈的:

    改用map:

    map的第一個引數是lambda表示式,冒號前面的i作為形參,來自於array中的元素,冒號後面就是要返回的值。
    當然你也可以使用列表推導式來代替:
  4. filter用法與map類似:filter(func,seq),對seq中的元素進行過濾,返回符合條件的那些元素。
    比如返回array = [1, 2, 3, 4]中的所有奇數:

    這裡是對2取餘,返回結果為True的元素。那麼什麼情況下結果為True?Python裡面不為0,None或者null都是True。所以結果就是,偶數是False,奇數是True,返回所有奇數。
    列表推導式方案:
  5. reduce用法:reduce(func,seq),對seq中的每個元素進行func操作,最後彙總返回一個值。
    1. array = [1, 2, 3]所有元素的和:

      reduce會先將array裡面的頭兩個數分別作為x和y,求它們的和,然後把它的結果和第三個相加,再把結果和第四個相加,直到最後一個元素。
    2. array = [1, 2, 3]中的最大值:
    3. strings = ["abc", "abcd", "def"]中”abc”出現的總次數:

    第三個引數0是count的初始值。

  6. eval執行一個字串表示式,並返回表示式的值。

    再來個複雜點的:

    看不懂就算了,這玩意寫起來很飄逸,但是殺敵一千,自損八百。

  7. 裝飾器
    設計模式的中的裝飾器模式還記得吧,可以動態擴充套件一個類的功能,但是又不會修改這個類的原始碼,Java IO包大量採用了裝飾器模式,我們來看看Python是怎麼玩的。
    舉個簡單的例子吧,在一個函式執行前打日誌:

    輸出:

  8. 生成器yield是Python核心關鍵字,不懂生成器,基本上就是把Python當加強版的Shell在用。
    迭代是在程式開發中常用的操作,對一個列表進行遍歷。可是如果列表資料過多,比如有上億條,就會遇到問題,因為記憶體空間有限。生成器應運而生,舉個斐波那契數列的例子:

    輸出:

    配合send、next函式,生成器可以實現協程的功能:

    輸出:

    呼叫next函式後,程式碼執行到yield,因為後面沒有任何值,所以列印出來的結果是None,此時程式碼hold住,讓出CPU。呼叫send(2)後程式碼恢復執行,將2賦給n然後列印,yield自帶next函式功能,程式碼繼續執行到yield,周而復始。通過生成器在單執行緒的情況下實現了任務排程。

  9. for/else我們經常使用for迴圈來查詢元素,有兩個場景會使迴圈停下來:
    1. 元素被找到,觸發break。
    2. 迴圈結束。
      但是我們並不知道是哪個原因導致迴圈結束,通常是設定一個標記,元素被找到,改變標記的值。for/else可以很優雅地解決這個問題:

 

相關文章