python標(biāo)準(zhǔn)庫(kù)簡(jiǎn)介(五)collections模塊一

1 collections 模塊

python 為我們提供了四種基本的容器數(shù)據(jù)類(lèi)型 list,tuple,dict,set。在大部分處理集合類(lèi)型數(shù)據(jù)的應(yīng)用場(chǎng)景,這四種數(shù)據(jù)結(jié)構(gòu)都能輕松勝任。但是在處理大量數(shù)據(jù)和處理復(fù)雜數(shù)據(jù)元素運(yùn)算的時(shí)候,這四中數(shù)據(jù)結(jié)構(gòu)明顯功能單一,且運(yùn)算效率較低。python標(biāo)準(zhǔn)庫(kù)為我們提供了collections包,里面提供很多功能強(qiáng)大的容器類(lèi)型,熟練掌握這些容器類(lèi)型,有助于提高我們的代碼質(zhì)量。這里主要介紹如下幾種數(shù)據(jù)結(jié)構(gòu)。

  • namedtuple
  • OrderedDict
  • defaultdict

2 namedtuple

2.1簡(jiǎn)介

namedtuple是一個(gè)函數(shù),創(chuàng)建一個(gè)自定義的tuple對(duì)象,規(guī)定tuple元素個(gè)數(shù)以及其對(duì)應(yīng)的屬性,可以根據(jù)屬性而不是索引來(lái)訪問(wèn),具有tuple的不變性,又可以根據(jù)屬性來(lái)引用。創(chuàng)建的namedtuple是tuple類(lèi)型的子類(lèi)。


In [2]: from collections import namedtuple

In [3]: Point = namedtuple('Ponit',['x','y'])

In [4]: p = Point(1,2)

In [5]: p.x
Out[5]: 1

In [6]: p.y
Out[6]: 2

In [7]: type(p)
Out[7]: __main__.Ponit

In [8]: isinstance(p,tuple)
Out[8]: True


In [9]: p.x=5
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-9-c7ca42e996c7> in <module>()
----> 1 p.x=5

AttributeError: can't set attribute

2.2 自帶描述信息

  • 單純的看一個(gè)元組的信息,我們很難看出元組以及元組每一項(xiàng)所表示的含義,采用namedtuple后,相當(dāng)于給元組增加了文檔描述。
  • namedtuple實(shí)例沒(méi)有對(duì)象字典,是一個(gè)輕量級(jí)數(shù)據(jù)結(jié)構(gòu),與普通元組相比并不需要更多內(nèi)存。這使得他們比字典更快。

下面代碼清楚的描述了一個(gè)圓的信息,circle相比較于circle2就要清楚太多了。

In [11]: Circle = namedtuple('Circle',['point','r'])

In [12]: circle = Circle(p,'5')

In [13]: circle
Out[13]: Circle(point=Ponit(x=1, y=2), r='5')

In [14]: circle.point.x
Out[14]: 1

In [15]: circle.point.y
Out[15]: 2

In [16]: circle.r
Out[16]: '5'

In [17]: circle2 = ((1,2),5)

In [18]: circle2
Out[18]: ((1, 2), 5)

2.3 實(shí)用方法

namedtuple是tuple的子類(lèi),具有tuple的所有方法

In [23]: p1 = Point(2,3)

In [24]: p2 = Point(3,4)

In [25]: p1+p2
Out[25]: (2, 3, 3, 4)

In [26]: p1.index(0)

In [27]: p1.index(2)
Out[27]: 0

In [29]: p1.count(1)
Out[29]: 0

In [30]: len(p1)
Out[30]: 2

namedtuple提供了其他方法讓我么更靈活的使用該數(shù)據(jù)結(jié)構(gòu)

In [46]: p._asdict()
Out[46]: OrderedDict([('x', 1), ('y', 2)])

In [47]: p._fields
Out[47]: ('x', 'y')

In [49]: p._make([1,2]) #傳入可迭代類(lèi)型
Out[49]: Ponit(x=1, y=2)

In [51]: p._replace(x=1,y=3) # 傳入**kwds
Out[51]: Ponit(x=1, y=3)

3 OrderedDict

3.1 簡(jiǎn)介

python 中的dict是無(wú)序的,在對(duì)dict做迭代時(shí)我們無(wú)法確定dict的順序。

OrderedDict是dict的子類(lèi),支持一般的dict方法,它會(huì)記錄key加入的順序,從而實(shí)現(xiàn)有序字典,這種數(shù)據(jù)結(jié)構(gòu)具有強(qiáng)大的威力。

In [65]: d = dict([('a',1),('b',2),('c',3)])

In [66]: d
Out[66]: {'a': 1, 'b': 2, 'c': 3}

In [67]: od = OrderedDict([('a',1),('b',2),('c',3)])

In [68]: od
Out[68]: OrderedDict([('a', 1), ('b', 2), ('c', 3)])

In [70]: od = OrderedDict()

In [71]: od['z']=1

In [72]: od['x']=2

In [73]: od['y']=3

In [74]: od
Out[74]: OrderedDict([('z', 1), ('x', 2), ('y', 3)])

In [75]: for i in od:
    ...:     print(i)
    ...:     
z
x
y

OrderedDict會(huì)按照其插入的順序給予鍵值對(duì)以固定的順序,這樣就可以得到“穩(wěn)定”的迭代對(duì)象,并且可以取出固定位置的鍵值對(duì)

In [88]: od
Out[88]: OrderedDict([('z', 1), ('x', 2), ('y', 3)])

In [89]: od.get([x for x in od][2])
Out[89]: 3

3.2根據(jù)字典的鍵或值的特征進(jìn)行排序

實(shí)現(xiàn)靈活排序

In [90]: d = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}

In [91]: OrderedDict(sorted(d.items(), key=lambda t: t[0])) # 按照鍵排序
Out[91]: OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])

In [92]: OrderedDict(sorted(d.items(), key=lambda t: t[1])) # 按照值排序
Out[92]: OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])

In [93]: OrderedDict(sorted(d.items(), key=lambda t: len(t[0]))) # 按照鍵長(zhǎng)度排序
Out[93]: OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)])

# tips: sorted函數(shù)key變量,是指在對(duì)可迭代對(duì)象排序的時(shí)候,按照可迭代對(duì)象的什么特征進(jìn)行排序

In [101]: a = ['5','40','345','6000']

In [102]: sorted(a #字符串第一個(gè)字符
Out[102]: ['345', '40', '5', '6000']

In [103]: sorted(a,key=lambda t:int(t)) #字符竄轉(zhuǎn)化為int型之后
Out[103]: ['5', '40', '345', '6000']

這樣就實(shí)現(xiàn)了對(duì)字典元素的順序的定義

3.3 OrderedDict 相關(guān)方法

根據(jù)可迭代對(duì)象生成值為None 的有序字典

In [109]: d = OrderedDict.fromkeys('abcde')

In [110]: d
Out[110]: OrderedDict([('a', None), ('b', None), ('c', None), ('d', None), ('e', None)])
In [9]: d.move_to_end('b')

In [10]: d
Out[10]: OrderedDict([('a', None), ('c', None), ('d', None), ('e', None), ('b', None)])

In [11]: d.popitem()
Out[11]: ('b', None)

In [12]: d.popitem()
Out[12]: ('e', None)

In [13]: d
Out[13]: OrderedDict([('a', None), ('c', None), ('d', None)])

4 defaultdict

4.1 簡(jiǎn)介

默認(rèn)值字典

python的dict數(shù)據(jù)類(lèi)型在取值dict[key]的時(shí)候如果沒(méi)有key會(huì)報(bào)錯(cuò),defaultdict通過(guò)則避免了這一行為.使用defaultdict,只要你傳入一個(gè)默認(rèn)的工廠方法,那么請(qǐng)求一個(gè)不存在的key時(shí), 便會(huì)調(diào)用這個(gè)工廠方法使用其結(jié)果來(lái)作為這個(gè)key的默認(rèn)值。

其原理是在dict基礎(chǔ)上實(shí)現(xiàn)了_missing_會(huì)調(diào)用傳入的工廠方法 當(dāng)_getitem_不存在的時(shí)候,就會(huì)觸發(fā),給本來(lái)不存在的鍵賦默認(rèn)值

工廠方法默認(rèn)為None,這個(gè)時(shí)候由于缺少工廠方法,對(duì)不存在的建設(shè)置默認(rèn)值就不會(huì)生效


In [53]: d = defaultdict()

In [54]: d
Out[54]: defaultdict(None, {})

In [55]: d['a']
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-55-4ff0d9af6f7a> in <module>()
----> 1 d['a']

KeyError: 'a'

當(dāng)傳入工廠方法的時(shí)候,設(shè)置默認(rèn)值就會(huì)生效.

In [56]: d = defaultdict(list)

In [57]: d['a']
Out[57]: []

In [58]: d
Out[58]: defaultdict(list, {'a': []})

In [59]: d.get('a')
Out[59]: []

In [60]: d['a']
Out[60]: []

4.2 實(shí)現(xiàn)序列元素的收集

可以利用defaultdict實(shí)現(xiàn)序列元素的分類(lèi)收集


In [34]: members = [
   ...:     # Age, name
   ...:     ['male', 'John'],
   ...:     ['male', 'Jack'],
   ...:     ['female', 'Lily'],
   ...:     ['male', 'Pony'],
   ...:     ['female', 'Lucy'],
   ...: ]

In [35]: result = defaultdict(list)
   ...: for sex, name in members:
   ...:     result[sex].append(name)
   ...:

In [36]: result
Out[36]: defaultdict(list,{'female': ['Lily', 'Lucy'], 'male'['John', 'Jack', 'Pony']}

In [37]: result['male']
Out[37]: ['John', 'Jack', 'Pony']

當(dāng)不存在key時(shí)候就會(huì)自動(dòng)調(diào)用list工廠函數(shù),產(chǎn)生一個(gè)空的列表,
上面的代碼片段就實(shí)現(xiàn)了對(duì)具有相同信息的序列結(jié)構(gòu)的篩選.使用dict可用如下方式實(shí)現(xiàn).

In [39]: d = {}

In [40]: for sex, name in members:
    ...:     d.setdefault(sex,[]).append(name)
    ...:     

In [41]: d
Out[41]: {'female': ['Lily', 'Lucy'], 'male': ['John', 'Jack', 'Pony']}

帶有默認(rèn)值的字典

In [49]: f = lambda :'chaoge'

In [50]: d = defaultdict(f)

In [51]: d['a']
Out[51]: 'chaoge'

In [52]: d
Out[52]: defaultdict(<function __main__.<lambda>>, {'a': 'chaoge'})
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容