Sharing

2011年10月24日 星期一

Python 學習手冊第三版筆記 (三)


Ch.10 Python 敘述簡介

None

Ch.11 指定敘述、運算式、以及列印

Python 會建立臨時之 tuple,以儲存右側變數原始之值,所以在交換兩變數之值,就很方便,不過我做了個小實驗,刻意的讓它交換兩次,原以為會有交換兩次的狀況,但發現沒有,也找不到合理的解釋來滿足第三個及第四個例子,所以目前還是不太清楚它是怎麼運作的,總之,少寫這樣會讓人看不懂的式子吧!

>>> A = 1
>>> B = 2
>>> A, B = B, A
>>> A, B
(2, 1)
>>> A, B, C = 1, 2, 3
>>> A, B, C
(1, 2, 3)
>>> A, B, C = B, C, A = C, A, B
>>> A, B, C
(2, 3, 1)
>>> A1, B1, C1 = 1, 2, 3
>>> A2, B2, C2 = 4, 5, 6
>>> A1, B1, C1 = B1, C1, A1 = A2, B2, C2
>>> A1, B1, C1
(6, 4, 5)
>>> A1, B1, C1 = 1, 2, 3
>>> A2, B2, C2 = 4, 5, 6
>>> A3, B3, C3 = 7, 8, 9
>>> A1, B1, C1 = A2, B2, C2 = A3, B3, C3
>>> A1, B1, C1
(7, 8, 9)

  • 單一底線的名稱 (_X) 不會被 from module import * 匯入,可以用來分辨這是公用函式或是私用函式

  • 前後有雙底線的名稱 (__X__) 是系統定義名詞,也不要隨意使用

  • 以兩底線開頭、但結尾沒有雙底線 (__X) 是類別之區域變數

  • 可利用 sys.stdout = open(xxxx) 來重導向輸出串流

  • 可以用 print >> file, [...] 來印東西到檔案中

  • 如果物件有定義 write 函式,也可以用 print >> object, [...] 來輸入東西


  • Ch.12 if 測試

  • X or Y or ... : Python 會由左至右求算運算元物件,然後傳回第一個為真者,不然就就傳回最後一個

  • X and Y and ... : 傳回第一個為假者,不然就傳回最後一個

  • if / else 三元運算式,有幾種表示法


  • if X:
        A = Y
    else:
        A = Z
    
    A = Y if X else Z
    
    A = ((X and Y) or Z)
    
    A = [Z, Y][bool(X)]
    
    

    如果用布林值 (or 、and) 來做運算,要注意的是可能不會執行所有的運算式,這和 C 也是一樣的

    Ch.13 while 與 for 迴圈


    和 C 不太一樣的部份有兩個

    1. 多了  pass 語法,代表的是什麼事也不做, 不過就和書上寫的一樣,真的有用的程式碼似乎都不太會用到這個語法, 比較像是我們在開發過程中, 有時候會寫上註解 /* TODO:  */ ,留下空白的內容,計劃之後再補上,這個時候可以先用 pass 來代替這個部份,所以目前我想像中的可能性是我寫完程式碼後可以回頭檢查有沒有 "pass" 留在程式碼中,如果有的話就表示我有東西忘了補。
    2. .
    3. 可以和 else 做搭配。以前寫 C 時, 會遇到一些 case, 在 for 迴圈之後,判斷 counter 是否有執行到最後,如果有才會觸發某些事,如果是中途就中斷的,就會跳過,我覺得這個有些相似,可以強化彼此的關係,讓可讀性更強。不過 while/for 和 else 搭配, 看起來真的很不習慣

    C 的寫法
    while (x > 1)
    {
           if ((y % x) == 0) 
           {
              printf(" y has factor %d\n", x);
              break;
           }
           x--           
    }
    
    if (x == 1)
         printf("y is prime\n");
    


    Python 的寫法
    while x > 1:
        if y % x == 0:
            print 'y has facter %d' % x
            break;
        x = x - 1
    else:
        print 'y is prime'
    
    

    過去用 C 寫遞迴的邏輯,是有一個 counter 時,而且可以清楚有上限時,就用 for loop,否則就用 while loop,但在 Python 當中它把 for loop 更抽像化一層,如果是在一個集合中想要輪流對每一個子元素操作時,就用 for loop,否則用 while loop ,用 for loop 的好處是有些物件會定義反覆器 (iterator? ),幫助更快速的存取子元素,而且可以在Python虛擬機器中做最佳化處理


    D = {'a':1, 'b':2, 'c':3}
    # 不使用反覆器
    for key in D.keys() :
        print key, D[key]
    
    # 使用 Dictionary 內建的反覆器
    for key in D
        print key, D[key]
    
    這兩種方式可以達到一樣的結果, 但效能卻不一樣, 後者會更好
    
    

    zip: 把兩個序列平行串接起來, 當引數長度不同時,zip 會以最短序列為主來截斷其它的序列,拿來建構辭典很方便

    >>> S1 = 'abc'
    >>> S2 = 'xyz123'
    >>> zip(S1, S2)
    [('a', 'x'), ('b', 'y'), ('c', 'z')]
    
    

    map: 和 zip 類似, 但會以最長序列為主來做 mapping

    >>> map(None, S1, S2)
    [('a', 'x'), ('b', 'y'), ('c', 'z'), (None, '1'), (None, '2'), (None, '3')]
    


    如果要施加一種運算至集合中的每個項目, 也可以利用 List comprehension
    >>> L = [1,2,3,4,5]
    
    # 利用 for loop
    >>> for i in range(5):
     L[i] += 10
    >>> L
    [11, 12, 13, 14, 15]
    
    # 利用 List comprehension 做一樣的事
    
    >>> L = [x+10 for x in L]
    >>> L
    [21, 22, 23, 24, 25]
    
    

    更複雜的 List comprehension

    >>> [x+y for x in 'abc' for y in 'lmn']
    ['al', 'am', 'an', 'bl', 'bm', 'bn', 'cl', 'cm', 'cn']
    

    Ch.14 說明文件插曲

    無特別紀錄

    沒有留言: