流暢的python筆記
1、collection.nametuple是一個工廠函數,可以很方便地定義一種數據類型,它具備tuple的不變性,又可以根據屬性來引用,使用十分方便,而不需要重新定義一個類那麽麻煩。
#nametuple的屬性和方法 City._fields #(‘name‘, ‘country‘, ‘population‘, ‘coordinates‘) _make(iterable) #類方法, 對可叠代對象進行實例化 _asdict() #實例方法,把nametuple以collections.OrderedDict的形式返回,使其友好呈現
2、定義類的一些技巧
importcollections Card = collections.namedtuple(‘Card‘, [‘rank‘, ‘suit‘]) #避免自定義class的麻煩 class FrenchDeck: ranks = [str(n) for n in range(2,11)] + list(‘JQKA‘) suits = ‘spades diamonds clubs hearts‘.split() def __init__(self): self._cards = [Card(rank,suit) for suit in self.suitsfor rank in self.ranks] def __len()__: return len(self._cards) def __getitem__(self, position): #實現該方法即實現可叠代,因此in運算符可以使用 return self._cards[position] #支持切片
3、
from math import hypot class Vector: def __init__(self, x=0, y=0): self.x = x self.y = ydef __repr__(self): #把一個對象用字符串的形式表達出來,__repr__比__str__是更好的選擇,__str__是給終端看的,__repr__調試用 return ‘Vector(%r, %r)‘ % (self.x, self.y) def __abs__(self): return hypot(self.x, self.y) def __bool__(self): return bool(abs(self)) # return bool(self.x, self.y)更高效,省掉abs到__abs__的轉化 def __add__(self, other): x = self.x + other.x y = self.y + other.y return Vector(x, y) def __mul__(self, scalar): return Vector(self.x * scalar, self.y * scalar)
還有一系列的特殊方法。
4、為什麽len不是普通的方法?運行更快。
5、
容器序列(存放不同類型):list, tuple, collections.deque
扁平序列(存放單類型): str, bytes, bytearray, memoryview, array.array
6、列表推導
codes = [ord(symbol) for symbol in symbols]
同filter和map的比較,列表推導都能做,而且不用lambda
beyond_ascii = [ord(s) for s in symbols if ord(s)>127] beyond_ascii = list(filter(lambda c:c>127, map(ord, symbols)))
7、生成器表達式:逐個生成,節省內存,註意是()
tuple(ord(symbol) for symbol in symbols)
8、可以使用*運算符把一個可叠代對象拆開作為函數的參數。
t = (20, 8) #可叠代對象 divmod(*t)
還可以使用*來獲取不確定的參數
a, b, *rest = range(5) #(0,1,[2,3,4])
9、二維的numpy可以使用二維切片 [ m:n, k:l ],如果x是四維數組,x[ i, ...] 就是 x[i, :, :, : ]。
如果賦值的對象是一個切片,那麽賦值右邊必須是個可叠代的對象。
l[ 2:5 ] = [100] #對 l[ 2:5 ] = 100 #錯
10、
board = [ [‘_‘] * 3 for i in range[3]] weird_board = [ [‘_‘] * 3] *3 #單點賦值會修改多個點,原因是列表內的3個引用指向同一個對象
11、
*= 在可變序列上不會改變序列ID,但在不可變的序列(如tuple)會改變ID,原因是對不可變序列進行重復拼接效率很低,因為每次都要把舊對象的元素賦值到新對象裏,再追加元素。
12、一個謎題
t = (1, 2, [30, 40]) t[2] += [50, 60] #結果有兩個: #元組不可賦值,會拋出異常,還會把t改變了: #t變成 ( 1, 2, [30, 40, 50, 60] )
鑒於上面的情況,建議:不要把可變對象放在元組裏面,增量賦值不是一個原子操作(像上面的例子)
13、list.sort 返回None,sorted返回新建的排序列表
14、使用bisect來管理已排序的序列。
#該模塊不會影響原排序 bisect.insort() #插入並改變原序列 bisect.bisect() #插入但不改變原序列 bisect.bisect_left() #插在重復數字的左邊,返回插入位置,不改變原序列
15、
存放大量浮點數是,數組(array)的效率更高。
檢查一個元素是否出現在一個集合中,set更合適。
如果只包含數字的列表,那麽array.array比list更高效。數組還提供從文件讀取和存入文件的更快的方法,如.frombytes和.tofile。
pickle.dump的處理速度和array.tofile一樣快。
16、內存視圖memoryview
讓用戶在不復制內容的情況下操作同一個數組的不同切片。
17、dict,defaultdict,OrderedDict
defaultdict在未找到的元素時,補上默認構造。(註意被__getitem__調用的__missing__方法)
dict.setdefault的妙用(一句頂三句):
index.setdefault(word, []).append(location) #檢索word,不存在則返回[ ],然後在該[ ]後添加位置。
if key not in my_dict:
my_dict[key] = []
my_dict[key].append(new_value)
流暢的python筆記