1. 開胃菜
注意: 官網下載的安裝文件自帶命令行執行窗口和 IDLE
2. 使用python解釋器
本章准備知識:
1. 設置安裝路徑
linux: export path=%path%;/usr/local/bin ----默認python會安裝在這個目錄下
win: set path=%path%;C:\python33 ----python在windows下的默認安裝環境
2. 退出 IDLE的方式
ctrl+d或者quit()
3. 檢查IDLE是否支持命令行編輯
ctrl+p ----如果主窗口顯示^p說明不支持;彈出一個窗口則說明支持
4. 啟用python解釋器的兩種方式
1. 在shell中執行*.py的腳本
2. python -c .[command] [arg] ----在 命令行 執行 Python 語句或模塊,一般建議將 命令 用單引號包裹起來
2.1. 調用 python 解釋器
2.1.1. 參數傳遞
情況一: 調用解釋器式沒有給定腳本和參數,直接打開解釋器舊式這種情況
>>> import sys>>> sys.argv[0]' ' ----空字符串
情況二: 腳本名指定為 '-' (表示標准輸入)時
$ python -
情況三: 使用 -c 指令 時, sys.argv[0] 被設定為 '-c' 。
情況四: 使用 -m 模塊 參數時, sys.agv[0] 被設定為指定模塊的全名
注:情況三、四 下參數不會被 Python 解釋器的選項處理機制所截獲,而是留在 sys.argv 中,供腳本命令操作
2.1.2. 交互模式
$ python3.3 ----進入交互模式 Python 3.3 (py3k, Sep 12 2007, 12:21:02) [GCC 3.4.6 20060404 (Red Hat 3.4.6-8)] on linux2Type "help", "copyright", "credits" or "license" for more information. >>> the_world_is_flat = 1 --------主提示符通常標識為三個大於號 (>>>) >>> if the_world_is_flat: ... print("Be careful not to fall off!") --------繼續的部分被稱為 從屬提示符 ... Be careful not to fall off!
2.2. 解釋器及其環境
2.2.1. 錯誤處理
1. 交互模式下,會打印錯誤信息並返回到主提示符,比如輸入中斷符會拋出KeyboardInterrupt異常
中斷符: 【ctrl+c】or 【del】
2. 執行文件的模式下會打印棧跟蹤器后以非零狀態退出
3. 可以用try語句中的except拉哎控制
2.2.2. 執行Python腳本
1. UNIX
腳本首行: #! /usr/bin/env python3.3
權限: $ chmod +x myscript.py
2. WIN
腳本首行: #! /usr/bin/env python3.3(不需要,即使有也會被當作一般注釋忽略)
權限: 不需要關心
雙擊: python安裝程序通過注冊表將.py關聯,.pyw也做了關聯,但不會顯示cmd窗口
2.2.3. 源程序編碼
1. python源文件默認是UTF-8編碼
2. 自定義文件的編碼
#! /usr/bin/env python3.3 # -*- coding: encoding -*- ----這個特殊的編碼注釋必須在文件中的 第一或第二 行定義
2.2.4. 交互執行文件
1. 每次解釋器啟動時執行一些命令
設定一個名為 PYTHONSTARTUP的環境變量來指定這個文件。
2. 如果你想要在當前目錄中執行附加的啟動文件
可以在全局啟動文件中加入類似以下的代碼:
if os.path.isfile('.pythonrc.py'): execfile('.pythonrc.py')import os
3. 如果你想要在某個腳本中使用啟動文件
必須要在腳本中寫入這樣的語句:
filename = os.environ.get('PYTHONSTARTUP')if filename and os.path.isfile(filename): exec(open(filename).read())
2.2.5. 本地化模塊
1. usercustomize
>>> import site>>> site.getusersitepackages() ----site-packages 目錄'/home/neo/.local/lib/python3.3/site-packages'
現在你可以在 site-packages 的目錄下創建 usercustomize.py 文件,內容就悉聽尊便了。 這個文件將會影響 python 的每次調用,除非啟動的時候加入 -s 選項禁止自動導入。
2. sitecustomize (和1類似)
但是是由電腦的管理賬戶創建以及在 usercustomize 之前導入。 具體可以參見 site 。
3. Python簡介
3.1. 將Python當作計算器
3.1.1. 數字
1. 取整除法: //
2. 連續賦值: x = y = z = 1
3. 變量使用前需要“定義”(即賦值)
4. 整數於浮點數混合計算是自動轉化為浮點數
5. 支持復數
>>> z = 2+1j / 2+1J/cpmplex(1,2)>>> z.real 2>>> z.imag 1>>> abs(z)>>>2.23606797749979
6. 數據類型轉換函數
int()/float()/long() ----不能用於復數
7. 監護模式下python會將最后一個變量的值賦給_
3.1.2. 字符串
1. 即可以用單引號也可以用雙引號標識
2. " "中只有 '不需要轉譯,' '中的 "不需要轉譯。
3. print()函數可以生成 更好的輸出4
4. 使用 \ 放在字符串尾來連接不同行的字符串
5. """或''': 三引號中的所有字串都將保持原樣,轉譯字符的轉移功能都會失效
6. 字符串可以用“+”連接,可以由"*"重復
7. 相鄰兩個字符串文本自動連接在一起(只針對字符串文本)
8. 沒有類似 c 的 char 類型
9. 字符串可以通過索引的方式截取,比如
>>> word = "hello" >>> word[0:1] ----相當於word[0] 或word(:1)'h'
10. python字符串不可變。想字符串某一個索引賦值會引發錯誤
11. 切片操作不變的一點s[:i]+s[i:] = s
12. 能夠優雅地處理沒有意義的索引方式
a. 索引大於字符串實際長度時將被實際長度替代
b. 上邊界大於下邊界這種情況將返回""
c. 索引也可以是負數,將導致從右邊開始算,-1代邊倒數第一個字符
+---+---+---+---+---+
| H | e | l | p | A |
+---+---+---+---+---+
0 1 2 3 4 5
-5 -4 -3 -2 -1
13. 內置函數 len() 返回字符串的長度
3.1.3. 關於Unicode
1. 通過對應unicode的序列號插入特殊字符
>>> 'Hello\u0020world!' ----'\u0020'是空格的unicode序列號>>> 'Hello world!'
2. 編碼小於256的unicode和latin-1編碼表示的字符是一致的
3. 通過已知字符串創建unicode編碼
>>> "abcس ".encode('utf-8') b'abc\xd8\xb3 '
3.1.4. 列表
1. 列表的元素不必是同一種類
2. 列表支持像字符串那樣索引/切片/連接
3. 切片操作返回的是對原列表淺拷貝的副本(意味着只是拷貝了指向同意空間的一些引用)
4. 列表允許修改元素
5. 列表可以通過賦值增大或通過清空某些元素減小
6. 列表可以使用內置函數 len() 計算元素的個數
7. 可以通過函數append()在列表末尾添加內容
3.2. 編程的第一步
1. python支持多重賦值: a, b = b, a+b ----先從左到右計算右邊的表達式然后才賦值
2. 任何非零整數/非空字符串/非空列表表示 true, 0/空字符串/空列表表示false
3. 使用縮進組織代碼,同意語句體需要同樣數量空白的縮進
4. print(): 通過逗號連接打印的內容,end=','結尾可以禁止換行
4. 深入Python流程控制
4.1. if語句
1. 一個實例:
>>> x = int(input('Pease input an integer:'))Please input an integer:>>> if x == 0:. . . print('zero'). . . elif x < 0: ----else ifx < 0:. . . print('below zero'). . . else:. . . print('above zero')
4.2. for語句
1. 一個實例
>>> a = ['a', 'ab', 'abc']>>> for x in a: . . . if len(x) > 2: . . . a.insert(0, x). . . >>> a['abc', 'a', 'ab', 'abc']
2. range()
>>> a = ['how ', 'do ', 'you ', 'know', '?']>>> for i in range(len(a)) . . . print(i, a[i]) . . . 0 how 1 do 2 you 3 know 4 ?
3. 可迭代對象
1. range()
>>> print(range(10)) range(0, 10) ----range()函數並不會在內存中構造一個列表,只會構造一個能夠按照期望返回序列的對象
2. 更多
4. 迭代器: 可以從可迭代對象迭代出序列
1. for循環
2. list():
>>> list(range(2)) [0,1, 2]
3. 更多
5. python的for或while循環可以有一個else語句(jave, js, c/c++等都不具有)
... for x in range(2, n): ... if n % x == 0: ... print(n, 'equals', x, '*', n//x)... break ... else: ----else語句在for迭代完畢或while條件判斷false時執行,如果迭代中發生break則跳過else語句... # loop fell through without finding a factor... print(n, 'is a prime number')...
4.3. break和continue語句,預計循環的else子句
1. break: 和c類似,略
2. continue: 和c類似,略
4.4. pass語句
1. pass 語句什么也不做。它用於那些語法上必須要有什么語句,但程序什么也不做的場合
2. 實例
>>> while True:... pass # Busy-wait for keyboard interrupt (Ctrl+C)...>>> class MyEmptyClass: ... pass ...>>> def initlog(*args): ... pass # Remember to implement this! ...
4.5. 定義函數
1. 一個實例
>>> def fib(n): # write Fibonacci series up to n ----可以將fib賦給其他變量 ... """Print a Fibonacci series up to n.""" ----可選的字符串文本(docstring),通過一些工具可以生成在線的文檔... a, b = 0, 1 ----函數內的變量賦值都是將值賦給函數被調用時創建的局部符號表... resule = [] ----一個鏈表對象... while a < n:... result.append(a) ... a, b = b, a+b ----引用變量的查找順序:(假設引用發生在函數內部)1.函數內部的局部變量表->2.包含函數名的局部變量表->3.全局符號表->4.內置符號表,全局變量不能在函數中直接賦值,除非用global語句... return result ...>>> # Now call the function we just defined: ... x = 2000 >>> fib(x) ----函數引用的實際參數在函數調用時引入局部符號表,通過傳值調用(復制)方式,只不過這里的值值得是引用地址,類似於java[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597]
4.6. 深入python函數定義
4.6.1. 默認參數值
1. 一個實例: 4個參數,3個給定默認值,調用時至少給一個實參,實參按順序賦給形參
def ask_ok(prompt, retries=4, complaint='Yes or no, please!'): while True: ok = input(prompt) if ok in ('y', 'ye', 'yes'): ----in: 測定序列中是否包含某個確定的值 return True if ok in ('n', 'no', 'nop', 'nope'): return False retries = retries - 1 if retries < 0: raise IOError('refusenik user') print(complaint)
2. 默認值只會在第一次調用時賦值一次,
4.6.2. 關鍵字參數
1. 一個實例
函數原型:
def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'): print("-- This parrot wouldn't", action, end=' ') print("if you put", voltage, "volts through it.") print("-- Lovely plumage, the", type) print("-- It's", state, "!")
用位置參數或關鍵字參數的形式調用:
parrot(1000) # 1 positional argumentparrot(voltage=1000) # 1 keyword argumentparrot(voltage=1000000, action='VOOOOOM') # 2 keyword argumentsparrot(action='VOOOOOM', voltage=1000000) # 2 keyword argumentsparrot('a million', 'bereft of life', 'jump') # 3 positional argumentsparrot('a thousand', state='pushing up the daisies') # 1 positional, 1 keyword
2. 參數列表必須(先書寫)位置參數然后才是關鍵字參數
這里關鍵字必須來自於形參名字
形參是否有一個默認值並不重要
任何參數都不能被多次賦值——在同一個調用中
與位置參數相同的形參名字不能用作關鍵字
3. *name: 這種類型的參數接受包含了所有沒有出現在形式參數列表中的參數值元組
4. **name: 接收一個包含了所有未出現在形式參數列表中的關鍵字參數的字典
5. 一個更全面的實例
函數原型:
def cheeseshop(kind, *arguments, **keywords): print("-- Do you have any", kind, "?") print("-- I'm sorry, we're all out of", kind) for arg in arguments: print(arg) print("-" * 40) keys = sorted(keywords.keys()) ----打印 關系字 參數字典的內容前先調用 sort() 方法。否則的話,打印參數時的順序是未定義的。 for kw in keys: print(kw, ":", keywords[kw]) 調用:cheeseshop("Limburger", "It's very runny, sir.", "It's really very, VERY runny, sir.", shopkeeper="Michael Palin",client="John Cleese", sketch="Cheese Shop Sketch")
4.6.3. 可變參數列表
1. 兩個實例:
def write_multiple_items(file, separator, *args): ----可變 參數是參數列表中的最后一個, 因為它們將把所有的剩余輸入參數傳遞給函數 file.write(separator.join(args))>>>def concat(*args, sep="/"): ----任何出現在 *args 后的參數是關鍵字參數,這意味着,他們只能被用作關鍵字,而不是位置參數... return sep.join(args)...>>> concat("earth", "mars", "venus")'earth/mars/venus'>>> concat("earth", "mars", "venus", sep=".")'earth.mars.venus'
4.6.4. 參數列表的分拆
1. 分拆元組
>>> list(range(3, 6)) # normal call with separate arguments[3, 4, 5]>>> args = [3, 6]>>> list(range(*args)) # call with arguments unpacked from a list[3, 4, 5]
2. 分拆字典
>>> def parrot(voltage, state='a stiff', action='voom'):... print("-- This parrot wouldn't", action, end=' ')... print("if you put", voltage, "volts through it.", end=' ')... print("E's", state, "!")...>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}>>> parrot(**d)-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !
4.6.5. Lambda形式
1. 一個實例
>>> def make_incrementor(n):... return lambda x: x + n ----類似函數式語言創建短小的匿名函數...>>> f = make_incrementor(42)>>> f(0)42>>> f(1)43
4.6.6. 文檔字符串
1. 一個實例
>>> def my_function():... """Do nothing, but document it.... ----留白“相當於”是字符串的起始縮進。每一行都不應該有縮進,如果有縮進的話,所有的留白都應該清除掉。... No, really, it doesn't do anything.... """... pass...>>> print(my_function.__doc__)Do nothing, but document it.No, really, it doesn't do anything. ----Python 的解釋器不會從多行的文檔字符串中去除縮進
4.7. 插曲:編程風格
5. 數據結構
5.1. 關於列表更多的內容
列表對象的所有方法:
list.append(x) ----把一個元素添加到鏈表的結尾,相當於 a[len(a):] = [x] 。
list.extend(L) ----將一個給定列表中的所有元素都添加到另一個列表中,相當於 a[len(a):] = L 。
list.insert(i, x) ----在指定位置插入一個元素。插在指定元素的前面。返回None
list.remove(x) ----刪除鏈表中值為 x 的第一個元素。如果沒有這樣的元素,就會返回一個錯誤。
list.pop([i]) ----從鏈表的指定位置刪除元素,並將其返回。如果沒有指定索引, a.pop() 返回最后一個元素。元素隨即從鏈表中被刪除。
list.index(x) ----返回鏈表中第一個值為 x 的元素的索引。如果沒有匹配的元素就會返回一個錯誤。
list.count(x) ----返回x在鏈表中出現的次數。
list.sort() ----對鏈表中的元素就地進行排序。返回None
list.reverse() ----就地到排鏈表中的元素。返回None
5.1.1. 把鏈表當作堆棧使用
1. 利用 list.append(x)和 list.pop([i])
2. 鏈表尾是棧頂
5.1.2. 把鏈表當作堆棧使用
1. 使用一般列表對象的方法: 效率不高,因為要移動整個
從鏈表頭入列: list.insert(0,x);從列表尾出列: list.pop()
從鏈表尾入列: list.append(x);從列表頭出列: list[i] = list[i+1]
2. 使用collections.deque,為首位兩端快速插入和刪除而設計
>>> from collections import deque ----導入這種對象類型>>> queue = deque(["Eric", "John", "Michael"]) ----將一般對象類型轉化為queue>>> queue.append("Terry") # Terry arrives ----在列表尾部入列>>> queue.append("Graham") # Graham arrives>>> queue.popleft() # The first to arrive now leaves ----在列表頭部出列'Eric'>>> queue.popleft() # The second to arrive now leaves'John'>>> queue # Remaining queue in order of arrivaldeque(['Michael', 'Terry', 'Graham'])
5.1.3. 列表推導式: 從已有的列表經過對每個元素的重新組合/篩選出新的列表
1. 一般方式創建列表:[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> square = [ ]>>> for x in range(10): . . . squares.append(x**2)
2. 通過列表推導式
>>> squares = [x**2 for x in range(10)]
3. 通過map的方式
>>> squares = map(lambda x: x**2, range(10))
5.1.4. 嵌套的列表推導式:轉置3x4的矩陣
1. 完全用一般語句實現
def row_to_line(matrix):"""a methord to reverse matrix"""transposed = []print(matrix)for i in range(len(matrix[0])): transposed_row = [] for row in matrix: transposed_row.append(row[i]) transposed.append(transposed_row)print(transposed)
2. 部分用列表推導式
def row_to_line2(matrix): """部分用列表推導式""" transposed = [] for i in range(len(matrix[0])): transposed.append([row[i] for row in matrix]) print(transposed)
3. 完全用列表推導式
def row_to_line3(matrix): """完全用列表推導式""" print([[row[i] for row in matrix] for i in range(len(matrix[0]))])
4. 使用內置函數
print(list(zip(*matrix)))
5.2. del語句
從列表中按給定的索引而不是值來刪除一個子項,也可以刪除整個變量。
>>> a = [1, 2, 3]>>> del a[0,2]>>> a>>> [3]
5.3. 元組與序列(元組是標准序列類型的一種)
1. 構造元組的形式
a. t = 12345, 54321, 'hello'
b. u = t, (1, 2, 3, 4, 5, 6)
c. v = 'hello', ----構造單個元素的元組
2. 元組的輸出總是右括號的
3. 不能給一個元組的獨立元素賦值
4. 序列拆封
>>> t = 12345, 54321, 'hello!' >>> x, y, z = t ----序列拆封要求左側的變量數目與序列的元素個數相同。
5.4. 集合
1. 幾個實例
>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}>>> a = set('abracadabra')>>> b = set('alacazam')>>> a # unique letters in a{'a', 'r', 'b', 'c', 'd'}>>> a - b # letters in a but not in b{'r', 'd', 'b'}>>> a | b # letters in either a or b{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}>>> a & b # letters in both a and b{'a', 'c'}>>> a ^ b # letters in a or b but not both{'r', 'd', 'b', 'm', 'z', 'l'}
2. 通過推導式構建集合
>>> a = {x for x in 'abracadabra' if x not in 'abc'}>>> a{'r', 'd'}
5.5. 字典(聯合內存/聯合數組)
1. 屬於python內建數據類型
2. 索引方式: 序列是以整數為索引,字典以關鍵字為索引
3. 關鍵字:
a. 任意不可變類型,比如字符串或數值
b. 元組如果包含可變對象不可以作為關鍵字
c. 鏈表不能作為關鍵字(因為可以改變)
4. del: 刪除鍵值對
5. list(d.key()) : 將返回一個字典中所有關鍵字組成的無序列表
4. sorted(d.key()): 將返回一個字典中所有關鍵字組成的有序列表
6. in: 檢查字典中是否存在某個鍵值
5.6. 循環技巧
-
iteritems() : 字典循環中鍵和值同時解讀
>>> knights = {'gallahad':'the pure','robin':'the brave'};>>> for k, v in knights.items(): print(k,v) robin the bravegallahad the pure
-
enumerate() : 序列循環中索引位置和對應值
>>> for i, v in enumerate(['tic', 'tac', 'toe']): print(i,v) 0 tic1 tac2 toe
-
zip() : 同時循環兩個或更多的序列
>>> questions = ['name', 'quest', 'favorite color'];>>> answers = ['lancelot', 'the holy grail', 'blue'];>>> for q, a in zip(questions, answers): print('what is your {0}? It is {1}.'.format(q,a)) what is your name? It is lancelot.what is your quest? It is the holy grail.what is your favorite color? It is blue.
-
reversed() : 逆向循環序列
>>> for i in reversed(range(1,10,2)): print(i) 97531
-
sorted() : 它不改動原序列,而是生成一個新的已排序的序列
>>> for f in sorted(set(basket)): print(f) applebananaorangepear
