Python 速查表中文版
- 本手冊是 Python cheat sheet 的中文翻譯版。原作者:Arianne Colton and Sean Chen(data.scientist.info@gmail.com)
- 編譯:ucasFL
目錄
- 常規
- 數值類型別
- 資料結構
- 函式
- 控制流
- 物件導向程式設計
- 常見字串操作
- 異常處理
- 列表、字典以及元組的推導表示式
- 單元測試
常規
- Python 對大小寫敏感
- Python 的索引從 0 開始
- Python 使用空白符(製表符或空格)來縮排程式碼,而不是使用花括號
獲取幫助
- 獲取主頁幫助:
help()
- 獲取函式幫助:
help(str.replace)
- 獲取模組幫助:
help(re)
模組(庫)
Python的模組只是一個簡單地以 .py
為字尾的檔案。
- 列出模組內容:
dir(module1)
- 匯入模組:
import module
- 呼叫模組中的函式:
module1.func1()
注:
import
語句會建立一個新的名稱空間(namespace),並且在該名稱空間內執行.py
檔案中的所有語句。如果你想把模組內容匯入到當前名稱空間,請使用from module1 import *
語句。
數值類型別
檢視變數的資料型別:type(variable)
六種經常使用的資料型別
-
int/long:過大的
int
型別會被自動轉化為long
型別 -
float:64 位,Python 中沒有
double
型別 -
bool:真或假
-
str:在 Python 2 中預設以 ASCII 編碼,而在 Python 3 中預設以 Unicode 編碼
-
字串可置於單/雙/三引號中
-
字串是字元的序列,因此可以像處理其他序列一樣處理字串
-
特殊字元可透過
\
或者字首r
實現:str1 = r'this\f?ff'
-
字串可透過多種方式格式化:
template = '%.2f %s haha $%d'; str1 = template % (4.88, 'hola', 2)
-
-
NoneType(None):Python “null”值(
None
物件只存在一個例項)-
None
不是一個保留關鍵字,而是NoneType
的一個唯一例項 -
None
通常是可選函式引數的預設值:def func1(a, b, c=None)
-
None
的常見用法:if variable is None :
-
-
datetime:Python內建的
datetime
模組提供了datetime
、data
以及time
型別。datetime
組合了儲存於date
和time
中的資訊
# 從字串中建立 datetime dt1 = datetime.strptime('20091031', '%Y%m%d') # 獲取 date 物件 dt1.date() # 獲取 time 物件 dt1.time() # 將 datetime 格式化為字串 dt1.strftime('%m/%d/%Y%H:%M') # 更改欄位值 dt2 = dt1.replace(minute=0, second=30) # 做差, diff 是一個 datetime.timedelta 物件 diff = dt1 - dt2
注:
str
、bool
、int
和float
同時也是顯式型別轉換函式。- 除字串和元組外,Python 中的絕大多數物件都是可變的。
資料結構
注:所有的“非只讀(non-Get)”函式呼叫,比如下面例子中的
list1.sort()
,除非特別宣告,都是原地操作(不會建立新的物件)。
元組
元組是 Python 中任何型別的物件的一個一維、固定長度、不可變的序列。
# 建立元組
tup1 = 4, 5, 6
tup1 = (6, 7, 8)
# 建立巢狀元組
tup1 = (4, 5, 6), (7, 8)
# 將序列或迭代器轉化為元組
tuple([1, 0, 2])
# 連線元組
tup1 + tup2
# 解包元組
a, b, c = tup1
元組應用:
# 交換兩個變數的值
a, b = b, a
列表
列表是 Python 中任何型別的物件的一個一維、非固定長度、可變(比如內容可以被修改)的序列。
# 建立列表
list1 = [1, 'a', 3]
list1 = list(tup1)
# 連線列表
list1 + list2
list1.extend(list2)
# 追加到列表的末尾
list1.append('b')
# 插入指定位置
list1.insert(PosIndex, 'a')
# 反向插入,即彈出給定位置的值/刪除
ValueAtIdx = list1.pop(PosIndex)
# 移除列表中的第一個值, a 必須是列表中第一個值
list1.remove('a')
# 檢查成員
3 in list1 => True or False
# 對列表進行排序
list1.sort()
# 按特定方式排序
list1.sort(key=len) # 按長度排序
- 使用 + 連線列表會有比較大的開支,因為這個過程中會建立一個新的列表,然後複製物件。因此,使用
extend()
是更明智的選擇。insert
和append
相比會有更大的開支(時間/空間)。- 在列表中檢查是否包含一個值會比在字典和集合中慢很多,因為前者需要進行線性掃描,而後者是基於雜湊表的,所以只需要花費常數時間。
內建的bisect
模組
-
對一個排序好的列表進行二分查詢或插入
-
bisect.bisect
找到元素在列表中的位置,bisect.insort
將元素插入到相應位置。 -
用法:
import bisect list1 = list(range(10)) #找到 5 在 list1 中的位置,從 1 開始,因此 position = index + 1 bisect.bisect(list1, 5) #將 3.5 插入 list1 中合適位置 bisect.insort(list1, 3.5)
注:
bisect
模組中的函式並不會去檢查列表是否排序好,因為這會花費很多時間。所以,對未排序好的列表使用這些函式也不會報錯,但可能會返回不正確的結果。
針對序列型別的切片
序列型別包括
str
、array
、tuple
、list
等。
用法:
list1[start:stop]
# 如果使用 step
list1[start:stop:step]
注:
- 切片結果包含
start
索引,但不包含stop
索引start/stop
索引可以省略,如果省略,則預設為序列從開始到結束,如list1 == list1[:]
。
step
的應用:
# 取出奇數位置的元素
list1[::2]
# 反轉字串
str1[::-1]
字典(雜湊表)
# 建立字典
dict1 = {'key1': 'value1', 2: [3, 2]}
# 從序列建立字典
dict(zip(KeyList, ValueList))
# 獲取/設定/插入元素
dict1['key1']
dict1['key1'] = 'NewValue'
# get 提供預設值
dict1.get('key1', DefaultValue)
# 檢查鍵是否存在
'key1' in dict1
# 獲取鍵列表
dict1.keys()
# 獲取值列表
dict1.values()
# 更新值
dict1.update(dict2) # dict1 的值被 dict2 替換
- 如果鍵不存在,則會出現
KeyError Exception
。- 當鍵不存在時,如果
get()
不提供預設值則會返回None
。- 以相同的順序返回鍵列表和值列表,但順序不是特定的,也就是說極大可能非排序。
有效字典鍵型別
- 鍵必須是不可變的,比如標量型別(
int
、float
、string
)或者元組(元組中的所有物件也必須是不可變的)。 - 這兒涉及的技術術語是“可雜湊(hashability)”。可以用函式
hash()
來檢查一個物件是否是可雜湊的,比如hash('This is a string')
會返回一個雜湊值,而hash([1,2])
則會報錯(不可雜湊)。
集合
-
一個集合是一些無序且唯一的元素的聚集;
-
你可以把它看成只有鍵的字典;
# 建立集合 set([3, 6, 3]) {3, 6, 3} # 子集測試 set1.issubset(set2) # 超集測試 set1.issuperset(set2) # 測試兩個集合中的元素是否完全相同 set1 == set2
-
集合操作
- 並(或):
set1 | set2
- 交(與):
set1 & set2
- 差:
set1 - set2
- 對稱差(異或):
set1 ^ set2
- 並(或):
函式
Python 的函式引數傳遞是透過引用傳遞。
-
基本形式
def func1(posArg1, keywordArg1=1, ..)
注:
- 關鍵字引數必須跟在位置引數的後面;
- 預設情況下,Python 不會“延遲求值”,表示式的值會立刻求出來。
-
函式呼叫機制
- 所有函式均位於模組內部作用域。見“模組”部分。
- 在呼叫函式時,引數被打包成一個元組和一個字典,函式接收一個元組
args
和一個字典kwargs
,然後在函式內部解包。
-
“函式是物件”的常見用法:
def func1(ops = [str.strip, user_define_func, ..], ..): for function in ops: value = function(value)
返回值
-
如果函式直到結束都沒有
return
語句,則返回None
。 -
如果有多個返回值則透過一個元組來實現。
return (value1, value2) value1, value2 = func1(..)
匿名函式(又稱 LAMBDA 函式)
-
什麼是匿名函式?
匿名函式是一個只包含一條語句的簡單函式。
lambda x : x * 2 # def func1(x) : return x * 2
-
匿名函式的應用:“柯里化(curring)”,即利用已存在函式的部分引數來派生新的函式。
ma60 = lambda x : pd.rolling_mean(x, 60)
一些有用的函式(針對資料結構)
-
Enumerate 返回一個序列
(i, value)
元組,i
是當前item
的索引。for i, value in enumerate(collection):
- 應用:建立一個序列中值與其在序列中的位置的字典對映(假設每一個值都是唯一的)。
-
Sorted 可以從任意序列中返回一個排序好的序列。
sorted([2, 1, 3]) => [1, 2, 3]
-
應用:
sorted(set('abc bcd')) => [' ', 'a', 'b', 'c', 'd'] # 返回一個字串排序後無重複的字母序列
-
-
Zip 函式可以把許多列表、元組或其他序列的元素配對起來建立一系列的元組。
zip(seq1, seq2) => [('seq1_1', 'seq2_1'), (..), ..]
-
zip()
可以接收任意數量的序列作為引數,但是產生的元素的數目取決於最短的序列。 -
應用:多個序列同時迭代:
for i, (a, b) in enumerate(zip(seq1, seq2)):
-
unzip
:另一種思考方式是把一些行轉化為一些列:seq1, seq2 = unzip(zipOutput)
-
-
Reversed 將一個序列的元素以逆序迭代。
list(reversed(range(10)))
reversed()
會返回一個迭代器,list()
使之成為一個列表。
控制流
-
用於
if-else
條件中的運算子:var1 is var2 # 檢查兩個變數是否是相同的物件 var1 is not var2 # 檢查兩個變數是否是不同的物件 var1 == var2 # 檢查兩個變數的值是否相等
注:Python 中使用
and
、or
、not
來組合條件,而不是使用&&
、||
、!
。 -
for
迴圈的常見用法:for element in iterator: # 可迭代物件(list、tuple)或迭代器 pass for a, b, c in iterator: # 如果元素是可以解包的序列 pass
-
pass
:無操作語句,在不需要進行任何操作的塊中使用。 -
三元表示式,又稱簡潔的
if-else
,基本形式:value = true-expr if condition else false-expr
-
Python 中沒有
switch/case
語句,請使用if/elif
。
物件導向程式設計
-
物件是 Python 中所有型別的根。
-
萬物(數字、字串、函式、類、模組等)皆為物件,每個物件均有一個“型別(type)”。物件變數是一個指向變數在記憶體中位置的指標。
-
所有物件均會被引用計數。
sys.getrefcount(5) => x a = 5, b = a # 上式會在等號的右邊建立一個物件的引用,因此 a 和 b 均指向 5 sys.getrefcount(5) => x + 2 del(a); sys.getrefcount(5) => x + 1
-
類的基本形式:
class MyObject(object): # 'self' 等價於 Java/C++ 中的 'this' def __init__(self, name): self.name = name def memberFunc1(self, arg1): pass @staticmethod def classFunc2(arg1): pass obj1 = MyObject('name1') obj1.memberFunc1('a') MyObject.classFunc2('b')
-
有用的互動式工具:
dir(variable1) # 列出物件的所有可用方法
常見字串操作
# 透過分隔符連線列表/元組
', '.join([ 'v1', 'v2', 'v3']) => 'v1, v2, v3'
# 格式化字串
string1 = 'My name is {0} {name}'
newString1 = string1.format('Sean', name = 'Chen')
# 分裂字串
sep = '-';
stringList1 = string1.split(sep)
# 獲取子串
start = 1;
string1[start:8]
# 補 '0' 向右對齊字串
month = '5';
month.zfill(2) => '05'
month = '12';
month.zfill(2) => '12'
month.zfill(3) => '012'
異常處理
-
基本形式:
try: pass except ValueError as e: print e except (TypeError, AnotherError): pass except: pass finally: pass # 清理,比如 close db;
-
手動引發異常:
raise AssertionError # 斷言失敗 raise SystemExit # 請求程式退出 raise RuntimeError('錯誤資訊 :..')
列表、字典以及元組的推導表示式
使程式碼更加易讀易寫的語法糖。
-
列表推導
-
用一個簡練的表示式,透過篩選一個資料集並且轉換經過篩選的元素的方式來簡明地生成新列表。
-
基本形式:
[expr for val in collection if condition]
等價於
result = [] for val in collection: if condition: result.append(expr)
可以省略過濾條件,只留下表示式。
-
-
字典推導
-
基本形式:
{key-expr : value-expr for value in collection if condition}
-
-
集合推導
- 基本形式:和列表推導一樣,不過是用
()
而不是[]
。
- 基本形式:和列表推導一樣,不過是用
-
巢狀列表
-
基本形式:
[expr for val in collection for innerVal in val if condition]
-
單元測試
Python自帶unittest
模組,可供我們編寫單元測試。
import unittest
我們可以編寫繼承於unittest.TestCase
測試類的子類,並在子類中編寫具體的測試函式。測試函式命必須以test_
開頭,否則不會被識別為測試函式,進而不會在執行單元測試時被執行。
class TestSubclass(unittest.TestCase):
def test_func(self):
self.assertEqual(0, 0)
# 可以透過msg關鍵字引數提供測試失敗時的提示訊息
self.assertEqual(0, 0, msg='modified message')
self.assertGreater(1, 0)
self.assertIn(0, [0])
self.assertTrue(True)
# 測試是否會丟擲異常
with self.assertRaises(KeyError):
_ = dict()[1]
# 被@unittest.skip裝飾器裝飾的測試類或測試函式會被跳過
@unittest.skip(reason='just skip')
def test_skip(self):
raise Exception('I shall never be tested')
另外,unittest.TestCase
中還有兩個特殊的成員函式,他們分別會在呼叫每一個測試函式的前後執行。在測試前連線資料庫並在測試完成後斷開連線是一種常見的使用場景。
def setUp(self):
# To do: connect to the database
pass
def tearDown(self):
# To do: release the connection
pass
def test_database(self):
# To do: test the database
pass
測試類編寫完畢後,可以透過新增以下程式碼來將當前檔案當成正常的Python指令碼使用
if __name__ == '__main__':
unittest.main()