流暢的python(筆記)

來源:互聯網
上載者:User

流暢的python中有很多奇技淫巧,整本書都在強調如何最大限度地利用Python 標準庫。介紹了很多python的不常用的資料類型、操作、庫等,對於入門python後想要提升對python的認識應該有協助。目前讀一遍記錄了一些有共鳴的操作:

Python內建序列類型的主要分類:

按可存放的元素類型分為:容器序列和扁平序列

  1. 容器序列,就是什麼都能作為元素往裡放,包括另一個序列。需要注意的是,如果元素是序列類型,那麼存放的往往是引用,需要小心。
    常見的容器序列包括:list,tuple,array.array,collections.deque等。
  2. 扁平序列,存放的都是原子級元素,此時存放的是值而不會是引用。
    常見的扁平序列包括:str,bytes,bytearray, memoryview, array.array等。

按序列能否被修改分為:可變序列與不可變序列

  1. 可變序列:可以進行增、刪、改等操作的序列,包括list, bytearray, array.array, collections.deque, memoryview等。
  2. 不可變序列:不可進行上述操作的序列,包括tuple, str, bytes等。
字典的變種

標準庫裡collections模組中提供了很多與字典類型相似的變種。

OrderDict: 這個類型在添加鍵的時候,會儲存順序,因此鍵的迭代順序總是一致的

ChainMap: 該類型可以容納數個不同的映射對像,在進行鍵的尋找時,這些對象會被當做一個整體逐個尋找,直到鍵被找到為止

Counter: 這個映射類型會給鍵準備一個整數技術器,每次更行一個鍵的時候都會增加這個計數器,所以這個類型可以用來給散列表對象計數,或者當成多重集來用。

UserDict: 這個類其實就是把標準的dict用Python又寫了一遍。一般用來給程式員想要通過繼承dict建立自己的dict時,代替dict使用的。主要是因為直接繼承原生dict會出現bug。

defaultdict:處理找不到的鍵的一個選擇
當某個鍵不在映射裡, 我們也希望也能得到一個預設值. 這就是 defaultdict , 它是 dict 的子類, 並實現了 missing 方法.

dict的實現以及導致的結果
鍵必須是可散列的:一個可散列的對象必須滿足以下要求。    (1) 支援 hash() 函數,並且通過 __hash__() 方法所得到的散列值是不變的。    (2) 支援通過 __eq__() 方法來檢測相等性。    (3) 若 a == b 為真,則 hash(a) == hash(b) 也為真。    所有由使用者自訂的對象預設都是可散列的,因為它們的散列值由 id() 來擷取,而    且它們都是不相等的。字典在記憶體上開銷很大(用記憶體換效率)。    元組取代字典就能節省空間的原因有兩個:    (1) 避免了散列表所耗費的空間,    (2) 無需把記錄中欄位的名字在每個元素裡都存一遍。鍵的查詢很快鍵的次序取決於添加順序往字典裡添加新鍵可能會改變已有鍵的順序
set的實現以及導致的結果
結合的元素必須是可散列的集合和消耗記憶體可以很高效的判斷元素是否存在於某個集合元素的次序取決於被添加到集合裡的順序往集合裡添加元素,可能會改變集合裡已有的元素次序
collections.namedtuple 可以用來構建一個帶欄位名的元組和一個有名字的類

建立一個具名元組需要兩個參數,一個是類名,另一個是類的各個欄位的名字。後者
可以是由數個字串組成的可迭代對象,或者是由空格分隔開的欄位名組成的字串。

>>> from collections import namedtuple>>> City = namedtuple('City', 'name country population coordinates')>>> tokyo = City('Tokyo', 'JP', 36.933, (35.689722, 139.691667)) >>> tokyoCity(name='Tokyo', country='JP', population=36.933, coordinates=(35.689722,139.691667))>>> tokyo.population 36.933>>> tokyo.coordinates(35.689722, 139.691667)>>> tokyo[1]'JP'>>> City = namedtuple('City_Name', 'name country population coordinates')>>> tokyo = City('Tokyo', 'JP', 36.933, (35.689722, 139.691667))>>> tokyoCity_Name(name='Tokyo', country='JP', population=36.933, coordinates=(35.689722, 139.691667))
當列表不是首選時
  1. 如果我們需要一個只包含數位列表,那麼 array.array 比 list 更高效。數組支援所
    有跟可變序列有關的操作,包括 .pop、.insert 和 .extend。另外,數組還提供從檔案
    讀取和存入檔案的更快的方法,如 .frombytes 和 .tofile。
  2. set 專為檢查元素是否存在做過最佳化
  3. memoryview 是一個內建類,它能讓使用者在不複製內容的情況下操作同一個數組的不同切
    片。
  4. 使用NumPy和SciPy提供的高階數組和矩陣操作
  5. 使用雙向隊列和其他形式的隊列(collections.deque 雙向隊列類、queue類中的 Queue、LifoQueue和PriorityQueue、multiprocessing. Queue、heapq可以把可變序列當作堆隊列或者優先隊列來使用)
Python 格式化輸出

在進行格式化輸出時,%r 與 %s 的區別就好比 repr() 函數處理對象與 str() 函數處理對象的差別。

  • %s -> str(),比較智能;
  • %r -> repr(),處理較為簡單和直接; 處理一些簡單對象時,二者幾乎沒有差別.

本文重點列舉一些二者的差異化用法:

  1. 處理字串時
>> s = 'world'>> print('hello %s'%s)hello world>> print('hello %r'%s)hello 'world'>> str(s)'world'>> repr(s)"'world'"2. datetime 庫中的 datetime 對象>> from datetime import datetime >> timeinfo = datetime.today()>> timeinfodatetime.datetime(2016, 6, 7, 21, 17, 34, 925488)>> type(timeinfo)datetime.datetime>> repr(timeinfo)'datetime.datetime(2016, 6, 7, 21, 17, 34, 925488)'>> str(timeinfo)'2016-06-07 21:17:34.925488'
反組譯碼函數 python opcode

Python dis 模組支援對Python代碼進行反組譯碼, 產生位元組碼指令。

In[1]: def test():...         x = 1...         if x < 3:...             return "yes"...         else:...             return "no"In[2]: dis.dis(test)  2           0 LOAD_CONST               1 (1)              3 STORE_FAST               0 (x)   3           6 LOAD_FAST                0 (x)              9 LOAD_CONST               2 (3)             12 COMPARE_OP               0 (<)             15 POP_JUMP_IF_FALSE       22   4          18 LOAD_CONST               3 ('yes')             21 RETURN_VALUE           6     >>   22 LOAD_CONST               4 ('no')             25 RETURN_VALUE                     26 LOAD_CONST               0 (None)             29 RETURN_VALUE        >>> def add(a, b = 0):...     return a + b... >>> >>> dis.dis(add)  2           0 LOAD_FAST                0 (a)              2 LOAD_FAST                1 (b)              4 BINARY_ADD              6 RETURN_VALUE>>>

class memoryview(obj)是python的內建類,如果要用memoryview 去引用一個object, 那麼這個object 必須支援buffer protocol, python3 中原生(built-in) 支援buffer protocol的obj有bytes和bytearray,memoryview可以使用不同的方式讀取和操作同一塊記憶體,並且原有的記憶體位元組不會隨意移動。類似於C中的強轉,好處是不會有記憶體拷貝。

例如,使用memoryview修改一個短整型有符號整數數組的資料。

from array import arrayfrom random import randomnumbers = array('h', [-2, -1, 0, 1, 2]) #signed shortmemv = memoryview(numbers)      #5個短整型有符號整數的數組建立一個memoryviewprint (len(memv))               #列印長度print (memv.tolist())           #轉換成列表形式memv_oct = memv.cast('B')       #記憶體共用 轉換成無符號字元類型print (memv_oct.tolist())memv_oct[5] = 4                 #把位置5的位元組賦值成4print (numbers)                 #因為我們把占 2 個位元組的整數的高位位元組改成了 4,所以這個有符號整數的值就變成了 1024輸出如下:5                       #數組長度[-2, -1, 0, 1, 2]       #列表形式顯示[254, 255, 255, 255, 0, 0, 1, 0, 2, 0]#長度擴大一倍 轉換為無符號字元類型array('h', [-2, -1, 1024, 1, 2])   #原來的數組被修改

bytearray是可變(mutable)的位元組序列,相對於Python2中的str,但str是不可變(immutable)的。
在Python3中由於str預設是unicode編碼,所以只有通過bytearray才能按位元組訪問。
下面兩種行為的對比:
簡單點就是,str和bytearray的切片操作會產生新的切片str和bytearry並拷貝資料,使用memoryview之後不會。

python2中的例子

不使用memoryview

a = 'aaaaaa'
b = a[:2] # 會產生新的字串

a = bytearray('aaaaaa')
b = a[:2] # 會產生新的bytearray
b[:2] = 'bb' # 對b的改動不影響a
a
bytearray(b'aaaaaa')
b
bytearray(b'bb')

使用memoryview

a = 'aaaaaa'
ma = memoryview(a)
ma.readonly # 唯讀memoryview
True
mb = ma[:2] # 不會產生新的字串

a = bytearray('aaaaaa')
ma = memoryview(a)
ma.readonly # 可寫的memoryview
False
mb = ma[:2] # 不會會產生新的bytearray
mb[:2] = 'bb' # 對mb的改動就是對ma的改動
mb.tobytes()
'bb'
ma.tobytes()
'bbaaaa'

Python 中有各種各樣可調用的類型,因此判斷置的 callable() 函數:

>>> abs, str, 13(<built-in function abs>, <class 'str'>, 13)>>> [callable(obj) for obj in (abs, str, 13)][True, True, False]
random.shuffle 打亂序列
>>> import random>>> a=range(10)>>> random.shuffle(a)>>> a[1, 0, 8, 5, 6, 7, 9, 3, 2, 4]>>> random.shuffle(a)>>> a[7, 5, 6, 2, 1, 8, 9, 0, 3, 4]
vim常用快捷
  • 0 → 數字零,到行頭
  • $ → 到本行行尾
  • a → 在游標後插入
  • o → 在當前行後插入一個新行
  • O → 在當前行前插入一個新行
  • cw → 替換從游標所在位置後到一個單詞結尾的字元
  • . → (小數點) 可以重複上一次的命令
  • NG → 到第 N 行 (注意命令中的G是大寫的,另我一般使用 : N 到第N行,如 :137 到第137行)
  • gg → 到第一行。(相當於1G,或 :1)
  • G → 到最後一行。
  • 在 Insert 模式下,你可以輸入一個詞的開頭,然後按或是,自動補齊功能就出現了…
內建函數
MathFunction    Descriptionabs()   Returns absolute value of a numberdivmod()    Returns quotient and remainder of integer divisionmax()   Returns the largest of the given arguments or items in an iterablemin()   Returns the smallest of the given arguments or items in an iterablepow()   Raises a number to a powerround() Rounds a floating-point valuesum()   Sums the items of an iterableType ConversionFunction    Descriptionascii() Returns a string containing a printable representation of an objectbin()   Converts an integer to a binary stringbool()  Converts an argument to a Boolean valuechr()   Returns string representation of character given by integer argumentcomplex()   Returns a complex number constructed from argumentsfloat() Returns a floating-point object constructed from a number or stringhex()   Converts an integer to a hexadecimal stringint()   Returns an integer object constructed from a number or stringoct()   Converts an integer to an octal stringord()   Returns integer representation of a characterrepr()  Returns a string containing a printable representation of an objectstr()   Returns a string version of an objecttype()  Returns the type of an object or creates a new type objectIterables and IteratorsFunction    Descriptionall()   Returns True if all elements of an iterable are trueany()   Returns True if any elements of an iterable are trueenumerate() Returns a list of tuples containing indices and values from an iterablefilter()    Filters elements from an iterableiter()  Returns an iterator objectlen()   Returns the length of an objectmap()   Applies a function to every item of an iterablenext()  Retrieves the next item from an iteratorrange() Generates a range of integer valuesreversed()  Returns a reverse iteratorslice() Returns a slice objectsorted()    Returns a sorted list from an iterablezip()   Creates an iterator that aggregates elements from iterablesComposite Data TypeFunction    Descriptionbytearray() Creates and returns an object of the bytearray classbytes() Creates and returns a bytes object (similar to bytearray, but immutable)dict()  Creates a dict objectfrozenset() Creates a frozenset objectlist()  Constructs a list objectobject()    Returns a new featureless objectset()   Creates a set objecttuple() Creates a tuple objectClasses, Attributes, and InheritanceFunction    Descriptionclassmethod()   Returns a class method for a functiondelattr()   Deletes an attribute from an objectgetattr()   Returns the value of a named attribute of an objecthasattr()   Returns True if an object has a given attributeisinstance()    Determines whether an object is an instance of a given classissubclass()    Determines whether a class is a subclass of a given classproperty()  Returns a property value of a classsetattr()   Sets the value of a named attribute of an objectsuper() Returns a proxy object that delegates method calls to a parent or sibling classInput/OutputFunction    Descriptionformat()    Converts a value to a formatted representationinput() Reads input from the consoleopen()  Opens a file and returns a file objectprint() Prints to a text stream or the consoleVariables, References, and ScopeFunction    Descriptiondir()   Returns a list of names in current local scope or a list of object attributesglobals()   Returns a dictionary representing the current global symbol tableid()    Returns the identity of an objectlocals()    Updates and returns a dictionary representing current local symbol tablevars()  Returns __dict__ attribute for a module, class, or objectMiscellaneousFunction    Descriptioncallable()  Returns True if object appears callablecompile()   Compiles source into a code or AST objecteval()  Evaluates a Python expressionexec()  Implements dynamic execution of Python codehash()  Returns the hash value of an objecthelp()  Invokes the built-in help systemmemoryview()    Returns a memory view objectstaticmethod()  Returns a static method for a function__import__()    Invoked by the import statement
跟運算子無關的特殊方法
類別 方法名字串 / 位元組序列表示形式 __repr__、__str__、__format__、__bytes__數值轉換 __abs__、__bool__、__complex__、__int__、__float__、__hash__、__index__集合類比 __len__、__getitem__、__setitem__、__delitem__、__contains__迭代枚舉 __iter__、__reversed__、__next__可調用類比 __call__上下文管理 __enter__、__exit__執行個體建立和銷毀 __new__、__init__、__del__屬性管理 __getattr__、__getattribute__、__setattr__、__delattr__、__dir__屬性描述符 __get__、__set__、__delete__跟類相關的服務 __prepare__、__instancecheck__、__subclasscheck__
Bisect模組管理有序的序列
bisect.bisect_left(a,x, lo=0, hi=len(a)) :尋找在有序列表 a 中插入 x 的index。lo 和 hi 用於指定列表的區間,預設是使用整個列表。如果 x 已經存在,在其左邊插入。傳回值為 index。bisect.bisect_right(a,x, lo=0, hi=len(a))bisect.bisect(a, x,lo=0, hi=len(a)) :這2個函數和 bisect_left 類似,但如果 x 已經存在,在其右邊插入。bisect.insort_left(a,x, lo=0, hi=len(a)) :在有序列表 a 中插入 x。和 a.insert(bisect.bisect_left(a,x, lo, hi), x) 的效果相同。bisect.insort_right(a,x, lo=0, hi=len(a))bisect.insort(a, x,lo=0, hi=len(a)) :和 insort_left 類似,但如果 x 已經存在,在其右邊插入。Bisect 模組提供的函數可以分兩類: bisect* 只用於尋找 index, 不進行實際的插入;而 insort* 則用於實際插入。
當list不是最優選擇時,dict是python的核心類型,但它是以空間換時間的結果,比較占記憶體,tuple是dict結構比較好的替代,set用來做是否包含和去重很合適。
from array import array  from random import randomfloats = array('d', (random() for i in range(10**7)))  fp = open('floats.bin', 'wb')floats.tofile(fp)  fp.close()floats2 = array('d')  fp = open('floats.bin', 'rb')floats2.fromfile(fp, 10**7)  fp.close()floats2 == floats
Python_內建四種隊列
from queue import Queue #LILO隊列q = Queue() #建立隊列對象q.put(0)    #在隊列尾部插入元素q.put(1)q.put(2)print('LILO隊列',q.queue)  #查看隊列中的所有元素print(q.get())  #返回並刪除隊列頭部元素print(q.queue)from queue import LifoQueue #LIFO隊列lifoQueue = LifoQueue()lifoQueue.put(1)lifoQueue.put(2)lifoQueue.put(3)print('LIFO隊列',lifoQueue.queue)lifoQueue.get() #返回並刪除隊列尾部元素lifoQueue.get()print(lifoQueue.queue)from queue import PriorityQueue #優先隊列priorityQueue = PriorityQueue() #建立優先隊列對象priorityQueue.put(3)    #插入元素priorityQueue.put(78)   #插入元素priorityQueue.put(100)  #插入元素print(priorityQueue.queue)  #查看優先順序隊列中的所有元素priorityQueue.put(1)    #插入元素priorityQueue.put(2)    #插入元素print('優先順序隊列:',priorityQueue.queue)  #查看優先順序隊列中的所有元素priorityQueue.get() #返回並刪除優先順序最低的元素print('刪除後剩餘元素',priorityQueue.queue)priorityQueue.get() #返回並刪除優先順序最低的元素print('刪除後剩餘元素',priorityQueue.queue)  #刪除後剩餘元素priorityQueue.get() #返回並刪除優先順序最低的元素print('刪除後剩餘元素',priorityQueue.queue)  #刪除後剩餘元素priorityQueue.get() #返回並刪除優先順序最低的元素print('刪除後剩餘元素',priorityQueue.queue)  #刪除後剩餘元素priorityQueue.get() #返回並刪除優先順序最低的元素print('全部被刪除後:',priorityQueue.queue)  #查看優先順序隊列中的所有元素from collections import deque   #雙端隊列dequeQueue = deque(['Eric','John','Smith'])print(dequeQueue)dequeQueue.append('Tom')    #在右側插入新元素dequeQueue.appendleft('Terry')  #在左側插入新元素print(dequeQueue)dequeQueue.rotate(2)    #迴圈右移2次print('迴圈右移2次後的隊列',dequeQueue)dequeQueue.popleft()    #返回並刪除隊列最左端元素print('刪除最左端元素後的隊列:',dequeQueue)dequeQueue.pop()    #返回並刪除隊列最右端元素print('刪除最右端元素後的隊列:',dequeQueue)以上隊列在多線程中可以使用的且安全執行緒,但在多進程中都不能用於通訊。在多進程中,需要這樣使用:from multiprocessing import Process, Queuemyqueue = Queue(100)## 參考80392493 www.cnblogs.com/cmnz/p/6936181.html
關鍵字
from keyword import kwlistprint(kwlist)
builtins模組
import builtinsdir(builtins)
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.