《Python核心編程》筆記(一)


大致地將《Python核心編程》的第一部分看完了,今後我將把在看這本書的過程中所記的一些筆記錄入於此,方便我以及其他有需要的朋友進行查閱。

** 注:本書為第二版,其中python的代碼主要為2.x版本,使用python3.x的朋友請留意。**

一些雜七雜八的小知識

  • enumerate函數

代碼示例:

1
2
3
foo = 'abc'
for i,ch in enumerate(foo):
print ch,'(%d)' % i

輸出:

1
2
3
a(0)
b(1)
c(2)
  • python通過引用調用,這意味著函數內對參數的改變會影響到原始對象。不過事實上只有可變對象會受到此影響,對於不可變對象來說,它的行為類似於按值調用。

  • **–init–()**是在對象創建之後執行的第一個方法,它並不創建實例,只是負責在創建之後做一些初始化工作。

  • 賦值並不是直接將一個值賦給一個變量,而是將對象(即值)的引用賦值給變量。並且賦值語句沒有返回值。

  • 交換兩值的技巧

代碼示例:

1
2
3
x,y = 1,2
x,y = y,x
#y = 1,x = 2
  • 所有的模塊都有能力來執行其自身的代碼,最高級別的python語句–那些沒有縮進的代碼行在模塊被導入時就會被執行,而不管是否真的需要去執行。所以除了主程序模塊,其他模塊中的代碼最好都封裝到函數或類中。

  • python解釋器在查找全局變量之前,總是先查找本地變量。因此有如下技巧:

    將經常用到的模塊屬性替換為一個本地引用,可以使得代碼的執行效率得到提高。

    如:ls = os.linesep(不同環境下的行終止符)

  • 通過id函數可以獲得對象的內存地址,用法:a = 2 id(a)

  • 下列對象的布爾值為False

    • None
    • False(布爾類型)
    • 所有值為零的數
    • 0.0
    • 0.0 + 0.0j
    • “”
    • []
    • ()
    • {}
  • foo1 = foo2 = 4.3與foo1 = 4.3 foo2 = foo1都表示foo1和foo2均指向一個值為4.3的對象,然而:
    foo1 = 4.3 foo2 = 1.3 + 3.0這時foo1和foo2指向不同的對象。

  • 引用計數每個對象天生有一個計數器,記錄它自己的引用次數,即表示有多少個變量指向該對象。python提供is 和 is not 來測試兩個變量是否指向同一個對象。

  • 整數對象和字符串對象均為不可變對象,所以python會很高效地緩存它們。這會造成我們認為python應該創建新對象時,它卻並沒有創建新對象:代碼示例如下:

1
2
3
4
5
6
7
a = 1
b = 1
#id(a) == id(b)

a = 1.0
b = 1.0
#id(a) != id(b)
  • python僅緩存簡單整數,如(-1,100),此範圍是會變的。另外,被緩存的字符串當無任何引用指向它時,該字符串將不會被緩存。

  • cmp(obj1,obj2)小於0,則obj1 < obj2;大於0,則obj1 > obj2;等於0,則obj1 == obj2;若要比較用戶自定義的對象,cmp函數會調用該類的特殊方法–cmp–()。

  • repr(obj)返回obj值的字符串表示,如:a = 2 repr(a) == ‘2’ b = ‘f’ repr(b) == “‘f’”。

  • 類型判斷用諸如type(a) is int這樣的語句對變量進行類型判斷,執行效率較高。

  • **isinstance(x,(int,float,…))**若該對象的類型在元組中,則函數返回True

  • Python3實現了真正的除法,即1 / 2 = 0.5而不是0,傳統除法(被稱為地板除)的運算符為”//“,如:1 // 2 = 0,1.0 // 2.0 = 0.0,1.0 // 3.0 = 0.0

  • 運算符**比左側的一元運算符優先級高,比右側的一元運算符優先級低。如:-3 ** 2 = -9,4.0 ** -1.0 = 0.25

  • Python3中,二進制數前綴為0b,0b10 = 2;八進制前綴:0o;十六進制前綴:0x

  • divmod()返回商和餘數的元組,oct(8) = 10;hex(16) = 10(oct函數轉十進制數到八進制,hex函數轉十六進制)

  • ascii轉換函數chr(97) = ‘a’ ord(‘a’) = 97 (意思明確,就不解釋了…)

  • random模塊

  • randint() 需要兩個整型參數,返回兩者之間的隨機整型

  • randrange() 返回range(start, stop[, step])序列中的一個整型數

  • uniform() 和randint()差不多,只不過返回兩者之間的浮點型(不包括範圍上限)

  • random() 返回0.0至1.0之間的一個浮點數

  • choice() 隨機返回給定序列中的一個元素

  • 鏈接操作符”+”可實現將兩個序列的內容合併,但效率不高,推薦的做法是:對於字符串,不如將所有的子字符串放到一個列表或可迭代的對象中,然後調用一個join方法來把所有內容連接到一起,從而節約內存,相關代碼如下:

1
2
3
a = ['h','e','l','l','o']
b = ''.join(a)
print(b) => 'hello'
  • split()與join()相反,它根據設定的分隔符將字符串分拆,相關代碼如下:
1
2
3
4
b = 'my..name..is..bob'
b.split('..') => ['my','name','is','bob']
b.split('..',2) => ['my','name','is..bob']
#其中上述代碼中的2若為-1,-2,-3...,則與沒有無異
  • 對於列表,append()用於向列表尾部添加一個新元素(該元素可為字符串,列表和元組),而extend()函數則是將一個新列表添加到原列表中,相關代碼如下:
1
2
3
a = [1,2]
a.extend([3,4])
a => [1,2,3,4]
  • [None]可使用”+”但不可使用extend()

  • for–elseelse只在for循環完整結束,沒遇到break的時候執行

  • ‘%s %s’ % (‘Spanish’,’Inquistion’) => ‘Spanish Inquistion’不過如下方法更好,因為更節約內存:
    a = ‘a’ ‘b’ => ‘ab’(注:’a’和’b’之間有空格都沒所謂)

  • map,filter,reduce

  • map(func, seq[, seq]) -> list 對seq中的item依次調用func,結果輸出為list。當傳入的參數為單個列表時,其原理圖如下:

    當傳入的參數為多個列表時,map會並行迭代每個序列,具體來說,就是第一次調用時,map會將每個序列的第一個元素捆綁到一個元組中,將func函數作用到map上,當map已經完成執行的時候,將元組的結果返回至map要返回的列表中,且作為第一個元素。其原理圖如下:

  • reduce(func, seq[, initial]) -> value
    reduce的參數為一個二元函數,一個序列和一個可選的初始化器,它的工作方式是(在沒有初始化器的情況下)取出序列的頭兩個元素,將它們傳入二元函數來獲得一個值,然後再用這個值與序列中的下一個元素傳入二元函數再獲得另外一個值。重複這一過程直到整個序列都被遍歷完畢。
    當初始化器存在的時候,則只取出序列中的頭一個元素,然後和初始化器一起傳入到二元函數中,然後再重複這一過程,其原理圖如下所示:

  • filter(func or None, seq) -> list, tuple or string
    filter函數的參數中的func應為一個布爾函數,filter會依次為序列中的每個元素調用func,然後將所有返回值為真的元素添加到一個序列中,其原理圖如下:

  • 字符串模板

代碼示例:

1
2
3
4
5
from string import Template
s = Template('There are ${howmany} ${lang} Quotation Symbols')
print(s.substitute(lang = 'python', howmany = 3))
#輸出There are 3 python Quotation Symbols.
#注:substitute函數的參數如果少了一個關鍵字參數,則會報錯,而若用safe_substitute(),則不會報錯,但會輸出原字符串。
  • zip()

代碼示例:

1
2
3
s, t = 'foa', 'obr'
zip(s, t)
=> [('f','o'),('o','b'),('a','r')]
  • 字符串排序使用字典序,而不是字母序。(‘T’ < ‘a’)

  • list.sort()與sorted()之區別:前者直接修改原列表,無返回值;後者創建新列表,原列表不變。

  • 元組對象本身不可變,但元組中包含的可變對象中的元素可變。如:元組中有一個列表,則列表中元素即可改變。

  • 所有的多對象,逗號分隔的,沒有明確使用符號定義的,這些集合的默認類型都為元組,舉例如下:

    1
    2
    4, 2 < 3, 5  #(4, True, 5)
    (4, 2) < (3, 5) #False
  • 淺拷貝和深拷貝由copy模塊提供。(自己翻書去吧…)

第一次的筆記比較混亂,因為我是按照書中章節來閱讀,然後從中截取一些我不太熟悉的知識點所造成的。之後的筆記相對來說會比較有條理一些,因為知識點相對集中一些。

《Python核心編程》筆記(一)

https://justuno.github.io/2014/03/13/python-course-1/

作者

Justuno

发布于

2014-03-13

更新于

2016-02-10

许可协议

评论