新聞中心
前言
本文繼續(xù)來盤Python內(nèi)置集合模塊,本期介紹其中的工具類雙端隊(duì)列類(Deque)、用戶列表類(UserList)和UserString類的使用。我們還是采用“短平快”的模式——文字+代碼,助你多“快好省地學(xué)會(huì)它,并能都收用上它。

1. Deque
Deque是棧和隊(duì)列的泛化(名字讀作“deck”,是“雙端隊(duì)列”的縮寫)。deque支持線程安全、內(nèi)存高效的從deque的任意一側(cè)添加和彈出操作,且在任何一個(gè)方向上都具有大致相同的O(1)性能。
盡管列表對(duì)象支持類似的操作,但它們都針對(duì)快速定長(zhǎng)操作進(jìn)行了優(yōu)化,并為pop(0)和insert(0, v)操作帶來O(n)內(nèi)存移動(dòng)成本,這兩種操作會(huì)改變底層數(shù)據(jù)表示的大小和位置。
導(dǎo)入Python集合模塊后,通過collections.deque([iterable[, maxlen]]),這會(huì)返回一個(gè)新的deque對(duì)象,用iterable的數(shù)據(jù)從左到右初始化(使用append())。如果未指定iterable,則新的deque為空。
可選參數(shù)maxlen,為deque的最大大小,如果未綁定則為None。如果未指定maxlen或?yàn)镹one,則deques可以增長(zhǎng)到任意長(zhǎng)度。否則,deque將被限定為指定的最大長(zhǎng)度。
需要注意的是,一旦指定邊界長(zhǎng)度的deque已滿,當(dāng)添加新項(xiàng)時(shí),相應(yīng)數(shù)量的項(xiàng)將從另一端丟棄??聪旅娴暮?jiǎn)單示例:
### Deque
from collections import deque
# 聲明一個(gè)deque對(duì)象,用可迭代對(duì)象初始化
q = deque(['user', 'password', 'token'])
print(q)
程序輸出結(jié)果如下:
D
Q
I
上面的清單中,通過傳遞一個(gè)列表作為參數(shù)來定義一個(gè)deque對(duì)象?,F(xiàn)在再創(chuàng)建另一個(gè),但這次使用的是字符串:
# 基于字符串創(chuàng)建含有3項(xiàng)的新deque對(duì)象
d = deque('dqi')
# 迭代遍歷deque元素
for elem in d:
print(elem.upper())
運(yùn)行程序的輸出結(jié)果如下:
|
D Q I |
現(xiàn)在來看看deque對(duì)象的內(nèi)容:
# deque的內(nèi)容列表
deque_contents = list(d)
print(deque_contents)
# 查看下最左邊項(xiàng)
print(d[0])
# 查看下最右邊項(xiàng)
print(d[-1])
運(yùn)行程序的結(jié)果輸出為:
['d', 'q', 'i']
d
i
接下來,簡(jiǎn)要看看deque對(duì)象支持的一些方法:
1)append(x):
將x添加到deque的右側(cè)。
2)appendleft(x):
在deque的左邊加上x。
示例如下:
# 在右邊添加新項(xiàng)
d.append('j')
# 在左邊添加新項(xiàng)
d.appendleft('f')
# 展示deque構(gòu)成表現(xiàn)
print(d)
輸出結(jié)果為:
deque(['f', 'd', 'q', 'i', 'j'])
3)pop():
從deque的右側(cè)刪除并返回一個(gè)元素。如果沒有元素,則引發(fā)IndexError。
4)popleft():
從deque的左側(cè)刪除并返回一個(gè)元素。如果沒有元素,則引發(fā)IndexError。
# 從右側(cè)刪除項(xiàng)并返回對(duì)應(yīng)項(xiàng)
rightmost = d.pop()
print(rightmost)
# 從左側(cè)刪除項(xiàng)并返回對(duì)應(yīng)項(xiàng)
leftmost = d.popleft()
print(leftmost)
輸出結(jié)果如下:
j
f
5)clear():
從deque中刪除所有元素,使其長(zhǎng)度為0。
6)copy():
創(chuàng)建deque的淺拷貝。
7)count(x):
計(jì)算等于x的deque元素的個(gè)數(shù)。
8)extend(iterable):
在deque的右側(cè)通過追加iterable參數(shù)中的元素來擴(kuò)展當(dāng)前對(duì)象。
# 一次增加多個(gè)元素
d.extend('jkl')
print(d)
輸出結(jié)果如下:
deque(['d', 'q', 'i', 'j', 'k', 'l'])
9)extendleft(iterable):
在deque對(duì)象的左側(cè)通過iterable中元素來追加來擴(kuò)展當(dāng)前對(duì)象。
注意,左追加的序列導(dǎo)致iterable參數(shù)中元素的順序顛倒。如下所示:
# extendleft() 反轉(zhuǎn)輸入順序
d.extendleft('xyz')
print(d)
輸出結(jié)果為:
deque(['z', 'y', 'x', 'd', 'q', 'i', 'j', 'k', 'l'])
10)index(x[,start[,stop]]):
返回x在deque中的位置(在索引start或之后和索引stop之前)。返回第一個(gè)匹配項(xiàng),如果未找到則引發(fā)ValueError異常。
11)insert(i ,x):
將x插入到deque中i的位置。如果插入會(huì)導(dǎo)致有界deque增長(zhǎng)超過maxlen,則拋出IndexError異常。
12)remove(value):
刪除第一個(gè)出現(xiàn)的值。如果沒有找到,則拋出ValueError。
13)rotate(n = 1):
向右輪轉(zhuǎn)deque n步。如果n是負(fù)數(shù),向左旋轉(zhuǎn),即把n個(gè)元素到左邊或右邊。
示例如下:
# 開始時(shí)deque
print(d)
#向右輪轉(zhuǎn)
d.rotate(1)
print(d)
# 向左輪轉(zhuǎn)
d.rotate(-1)
print(d)
d.rotate(3)
print(d)
輸出結(jié)果為:
deque(['z', 'y', 'x', 'd', 'q', 'i', 'j', 'k', 'l'])
deque(['l', 'z', 'y', 'x', 'd', 'q', 'i', 'j', 'k'])
deque(['z', 'y', 'x', 'd', 'q', 'i', 'j', 'k', 'l'])
deque(['j', 'k', 'l', 'z', 'y', 'x', 'd', 'q', 'i'])
14)reverse()
將deque的元素原地反轉(zhuǎn),然后返回None。
# 開始是deque
print('old deque:', d)
# 反轉(zhuǎn)deque中元素
new_deq = d.reverse()
print('new deque:', new_deq)
# 反轉(zhuǎn)后原始deque
print('old deque:', d)
輸出結(jié)果:
old deque: deque(['z', 'y', 'x', 'd', 'q', 'i', 'j', 'k', 'l'])
new deque: None
old deque: deque(['l', 'k', 'j', 'i', 'q', 'd', 'x', 'y', 'z'])
正如輸出結(jié)果所示,reverse()方法將deque的元素就地反轉(zhuǎn),這意味著我們的原始deque對(duì)象被修改了。它返回None。
提醒:由于Deque是線程安全,常用在多線程環(huán)境下使用,比如對(duì)象共享池、數(shù)據(jù)庫(kù)連接池等方法,還可以便利控制或說自定義隊(duì)列中的對(duì)象上限。
2. UserList
UserList類用于充當(dāng)列表對(duì)象的包裝器。對(duì)于你自己的創(chuàng)建類似列表類來說,它是一個(gè)有用的基類,可以繼承并覆蓋其現(xiàn)有的方法或添加新的方法。通過這種方式,可以向Python中的列表添加新的行為。
對(duì)這個(gè)類的需求已經(jīng)部分被直接來自list的子類能力所取代;但是,這個(gè)類更容易使用,因?yàn)榈讓恿斜砜梢宰鳛閷傩栽L問。其通常使用方式為:
import collections
ulist = collections.UserList([list])
該類模擬列表行為,其實(shí)例的內(nèi)容保存在一個(gè)常規(guī)列表中,可以通過UserList實(shí)例的data屬性訪問該列表。實(shí)例的內(nèi)容最初化為list的副本,默認(rèn)為空列表[]。參數(shù)list可以是任何可迭代對(duì)象,例如一個(gè)真正的Python列表或UserList對(duì)象。
除了支持可變序列的方法和操作外,UserList實(shí)例還提供了以下屬性:
data:
一個(gè)用于存儲(chǔ)UserList類內(nèi)容的真實(shí)列表對(duì)象。
假設(shè)我們想要定義一個(gè)不允許刪除其中項(xiàng)的列表。我們可以通過繼承UserList輕松定義這樣的類:
from collections import UserList
# 自定義一個(gè)類,其繼承自UserList
# 該類不允許刪除其所含項(xiàng)
# Python中的List類的刪除方法:
# remove() and pop()
class ListWithNoItemDelete(UserList):
# 覆寫remove()方法
def remove(self, s=None):
self.not_allowed()
# 覆寫 pop() 方法
def pop(self, s=None):
self.not_allowed()
# 定義一個(gè)不允許方法
def not_allowed(self):
raise RuntimeError("Deletion not allowed")
# 自定義列表對(duì)象
custom_list = ListWithNoItemDelete(['a', 'b', 'c'])
# 試圖刪除列表項(xiàng)操作
custom_list.remove('b')
運(yùn)行上述程序控制臺(tái)輸出類似如下內(nèi)容:
……
raise RuntimeError("Deletion not allowed")
RuntimeError: Deletion not allowed
使用建議:該類型主要特點(diǎn)是參數(shù)的副本化,即不會(huì)改變傳進(jìn)來的列表,同時(shí)多了個(gè)存儲(chǔ)屬性data,實(shí)際應(yīng)用中可酌情使用。
3. UserString
UserString類充當(dāng)字符串對(duì)象的包裝器。對(duì)該類的需求已經(jīng)部分被直接從str派生子類的能力所取代;但是,這個(gè)類更容易使用,因?yàn)榈讓幼址梢宰鳛閷傩栽L問。其通常使用形式:
import collections
userStr = collections.UserString(seq)
該類模擬字符串對(duì)象,其實(shí)例的內(nèi)容保存在一個(gè)常規(guī)字符串對(duì)象中,其可通過UserString實(shí)例的data屬性訪問該對(duì)象。實(shí)例的內(nèi)容最初化為seq的一個(gè)副本。seq參數(shù)可以是任何可以使用內(nèi)置str()函數(shù)轉(zhuǎn)換為字符串的對(duì)象。
除了支持字符串的方法和操作,UserString實(shí)例提供以下屬性:
data:
這是個(gè)str對(duì)象,用于存儲(chǔ)UserString類的內(nèi)容。
假設(shè)我們想要定義一個(gè)自己的str類,包含concatenate()方法,可以參考如下實(shí)現(xiàn):
# UserString
from collections import UserString
# 定義一個(gè)繼承自UserString的子類
class CustomStrClass(UserString):
# 定義一個(gè)新方法
def concatenate(self, other=None, delimiter=' '):
self.data += delimiter + other
# 創(chuàng)建自定義字符串對(duì)象
custom_str = CustomStrClass('My Custom')
custom_str.concatenate('String Class')
print(custom_str)
運(yùn)行程序,輸出結(jié)果類似如下:
My Custom String Class
概括:該字符串最大特色就是存儲(chǔ)的是參數(shù)副本,并具有可自行定制處理的機(jī)制以及data屬性。通常狀況下,str類即可。
4.本文小結(jié)
本期中主要介紹Python集合模塊中的雙端隊(duì)列(Deque)、用戶列表(UserList)以及用戶字符串(UserString),使用中要根據(jù)需要來結(jié)合他們各自的特點(diǎn)使用,比如deque的線程安全的支持和雙端操作、UserString與UserString的副本化及data存儲(chǔ)屬性等。
當(dāng)前標(biāo)題:Python編程:集合工具類之Deque及UserString和UserList
網(wǎng)址分享:http://m.fisionsoft.com.cn/article/ccoohss.html


咨詢
建站咨詢
