1. 程式人生 > >流暢的python筆記

流暢的python筆記

內存 可變 文件讀取 lec 文件 other 使用 card lar

1、collection.nametuple是一個工廠函數,可以很方便地定義一種數據類型,它具備tuple的不變性,又可以根據屬性來引用,使用十分方便,而不需要重新定義一個類那麽麻煩。

#nametuple的屬性和方法
City._fields #(‘name‘, ‘country‘, ‘population‘, ‘coordinates‘)

_make(iterable)  #類方法, 對可叠代對象進行實例化
_asdict()  #實例方法,把nametuple以collections.OrderedDict的形式返回,使其友好呈現

2、定義類的一些技巧

import
collections 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.suits
for 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 = y
  
  
def __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筆記