Python編程:集合工具類之Deque及UserString和UserList
前言
本文繼續來盤Python內置集合模塊,本期介紹其中的工具類雙端隊列類(Deque)、用戶列表類(UserList)和UserString類的使用。我們還是采用“短平快”的模式——文字+代碼,助你多“快好省地學會它,并能都收用上它。
1. Deque
Deque是棧和隊列的泛化(名字讀作“deck”,是“雙端隊列”的縮寫)。deque支持線程安全、內存高效的從deque的任意一側添加和彈出操作,且在任何一個方向上都具有大致相同的O(1)性能。
盡管列表對象支持類似的操作,但它們都針對快速定長操作進行了優化,并為pop(0)和insert(0, v)操作帶來O(n)內存移動成本,這兩種操作會改變底層數據表示的大小和位置。
導入Python集合模塊后,通過collections.deque([iterable[, maxlen]]),這會返回一個新的deque對象,用iterable的數據從左到右初始化(使用append())。如果未指定iterable,則新的deque為空。
可選參數maxlen,為deque的最大大小,如果未綁定則為None。如果未指定maxlen或為None,則deques可以增長到任意長度。否則,deque將被限定為指定的最大長度。
需要注意的是,一旦指定邊界長度的deque已滿,當添加新項時,相應數量的項將從另一端丟棄。看下面的簡單示例:
程序輸出結果如下:
上面的清單中,通過傳遞一個列表作為參數來定義一個deque對象。現在再創建另一個,但這次使用的是字符串:
運行程序的輸出結果如下:
D Q I |
現在來看看deque對象的內容:
運行程序的結果輸出為:
接下來,簡要看看deque對象支持的一些方法:
1)append(x):
將x添加到deque的右側。
2)appendleft(x):
在deque的左邊加上x。
示例如下:
輸出結果為:
3)pop():
從deque的右側刪除并返回一個元素。如果沒有元素,則引發IndexError。
4)popleft():
從deque的左側刪除并返回一個元素。如果沒有元素,則引發IndexError。
輸出結果如下:
5)clear():
從deque中刪除所有元素,使其長度為0。
6)copy():
創建deque的淺拷貝。
7)count(x):
計算等于x的deque元素的個數。
8)extend(iterable):
在deque的右側通過追加iterable參數中的元素來擴展當前對象。
輸出結果如下:
9)extendleft(iterable):
在deque對象的左側通過iterable中元素來追加來擴展當前對象。
注意,左追加的序列導致iterable參數中元素的順序顛倒。如下所示:
輸出結果為:
10)index(x[,start[,stop]]):
返回x在deque中的位置(在索引start或之后和索引stop之前)。返回第一個匹配項,如果未找到則引發ValueError異常。
11)insert(i ,x):
將x插入到deque中i的位置。如果插入會導致有界deque增長超過maxlen,則拋出IndexError異常。
12)remove(value):
刪除第一個出現的值。如果沒有找到,則拋出ValueError。
13)rotate(n = 1):
向右輪轉deque n步。如果n是負數,向左旋轉,即把n個元素到左邊或右邊。
示例如下:
輸出結果為:
14)reverse()
將deque的元素原地反轉,然后返回None。
輸出結果:
正如輸出結果所示,reverse()方法將deque的元素就地反轉,這意味著我們的原始deque對象被修改了。它返回None。
提醒:由于Deque是線程安全,常用在多線程環境下使用,比如對象共享池、數據庫連接池等方法,還可以便利控制或說自定義隊列中的對象上限。
2. UserList
UserList類用于充當列表對象的包裝器。對于你自己的創建類似列表類來說,它是一個有用的基類,可以繼承并覆蓋其現有的方法或添加新的方法。通過這種方式,可以向Python中的列表添加新的行為。
對這個類的需求已經部分被直接來自list的子類能力所取代;但是,這個類更容易使用,因為底層列表可以作為屬性訪問。其通常使用方式為:
該類模擬列表行為,其實例的內容保存在一個常規列表中,可以通過UserList實例的data屬性訪問該列表。實例的內容最初化為list的副本,默認為空列表[]。參數list可以是任何可迭代對象,例如一個真正的Python列表或UserList對象。
除了支持可變序列的方法和操作外,UserList實例還提供了以下屬性:
data:
一個用于存儲UserList類內容的真實列表對象。
假設我們想要定義一個不允許刪除其中項的列表。我們可以通過繼承UserList輕松定義這樣的類:
運行上述程序控制臺輸出類似如下內容:
使用建議:該類型主要特點是參數的副本化,即不會改變傳進來的列表,同時多了個存儲屬性data,實際應用中可酌情使用。
3. UserString
UserString類充當字符串對象的包裝器。對該類的需求已經部分被直接從str派生子類的能力所取代;但是,這個類更容易使用,因為底層字符串可以作為屬性訪問。其通常使用形式:
該類模擬字符串對象,其實例的內容保存在一個常規字符串對象中,其可通過UserString實例的data屬性訪問該對象。實例的內容最初化為seq的一個副本。seq參數可以是任何可以使用內置str()函數轉換為字符串的對象。
除了支持字符串的方法和操作,UserString實例提供以下屬性:
data:
這是個str對象,用于存儲UserString類的內容。
假設我們想要定義一個自己的str類,包含concatenate()方法,可以參考如下實現:
運行程序,輸出結果類似如下:
概括:該字符串最大特色就是存儲的是參數副本,并具有可自行定制處理的機制以及data屬性。通常狀況下,str類即可。
4.本文小結
本期中主要介紹Python集合模塊中的雙端隊列(Deque)、用戶列表(UserList)以及用戶字符串(UserString),使用中要根據需要來結合他們各自的特點使用,比如deque的線程安全的支持和雙端操作、UserString與UserString的副本化及data存儲屬性等。