在內(nèi)置數(shù)據(jù)類型(dict、list蒋伦、set、tuple)的基礎(chǔ)上焚鹊,collections模塊還提供了幾個額外的數(shù)據(jù)類型:Counter痕届、deque、defaultdict末患、namedtuple和OrderedDict等研叫。
- namedtuple: 生成可以使用名字來訪問元素內(nèi)容的tuple
- deque: 雙端隊列,可以快速的從另外一側(cè)追加和推出對象
- Counter: 計數(shù)器璧针,主要用來計數(shù)
- OrderedDict: 有序字典
- defaultdict: 帶有默認值的字典
namedtuple
我們知道tuple可以表示不變集合嚷炉,例如,一個點的二維坐標就可以表示成:
>>> p = (1, 2)
但是探橱,看到(1, 2)申屹,很難看出這個tuple是用來表示一個坐標的绘证。
這時,namedtuple就派上了用場:
>>> from collections import namedtuple
>>> Point = namedtuple('Point', ['x', 'y'])
>>> p = Point(1, 2)
>>> p.x
1
>>> p.y
2
類似的哗讥,如果要用坐標和半徑表示一個圓嚷那,也可以用namedtuple定義:
#namedtuple('名稱', [屬性list]):
Circle = namedtuple('Circle', ['x', 'y', 'r'])
deque
使用list存儲數(shù)據(jù)時,按索引訪問元素很快忌栅,但是插入和刪除元素就很慢了车酣,因為list是線性存儲,數(shù)據(jù)量大的時候索绪,插入和刪除效率很低湖员。
deque是為了高效實現(xiàn)插入和刪除操作的雙向列表,適合用于隊列和棧:
>>> from collections import deque
>>> q = deque(['a', 'b', 'c'])
>>> q.append('x')
>>> q.appendleft('y')
>>> q
deque(['y', 'a', 'b', 'c', 'x'])
deque除了實現(xiàn)list的append()和pop()外瑞驱,還支持appendleft()和popleft()娘摔,這樣就可以非常高效地往頭部添加或刪除元素。
OrderedDict
使用dict時唤反,Key是無序的凳寺。在對dict做迭代時,我們無法確定Key的順序彤侍。
如果要保持Key的順序肠缨,可以用OrderedDict:
>>> from collections import OrderedDict
>>> d = dict([('a', 1), ('b', 2), ('c', 3)])
>>> d # dict的Key是無序的
{'a': 1, 'c': 3, 'b': 2}
>>> od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
>>> od # OrderedDict的Key是有序的
OrderedDict([('a', 1), ('b', 2), ('c', 3)])
注意,OrderedDict的Key會按照插入的順序排列盏阶,不是Key本身排序:
>>> od = OrderedDict()
>>> od['z'] = 1
>>> od['y'] = 2
>>> od['x'] = 3
>>> od.keys() # 按照插入的Key的順序返回
['z', 'y', 'x']
defaultdict
有如下值集合 [11,22,33,44,55,66,77,88,99,90...]晒奕,將所有大于 66 的值保存至字典的第一個key中,將小于 66 的值保存至第二個key的值中名斟。
即: {'k1': 大于66 , 'k2': 小于66}
values = [11, 22, 33,44,55,66,77,88,99,90]
my_dict = {}
for value in values:
if value>66:
if my_dict.has_key('k1'):
my_dict['k1'].append(value)
else:
my_dict['k1'] = [value]
else:
if my_dict.has_key('k2'):
my_dict['k2'].append(value)
else:
my_dict['k2'] = [value]
from collections import defaultdict
values = [11, 22, 33,44,55,66,77,88,99,90]
my_dict = defaultdict(list)
for value in values:
if value>66:
my_dict['k1'].append(value)
else:
my_dict['k2'].append(value)
使用dict時脑慧,如果引用的Key不存在,就會拋出KeyError砰盐。如果希望key不存在時闷袒,返回一個默認值,就可以用defaultdict:
>>> from collections import defaultdict
>>> dd = defaultdict(lambda: 'N/A')
>>> dd['key1'] = 'abc'
>>> dd['key1'] # key1存在
'abc'
>>> dd['key2'] # key2不存在岩梳,返回默認值
'N/A'
Counter
Counter類的目的是用來跟蹤值出現(xiàn)的次數(shù)囊骤。它是一個無序的容器類型,以字典的鍵值對形式存儲蒋腮,其中元素作為key淘捡,其計數(shù)作為value。計數(shù)值可以是任意的Interger(包括0和負數(shù))池摧。Counter類和其他語言的bags或multisets很相似焦除。
c = Counter('abcdeabcdabcaba')
print c
輸出:Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1})
創(chuàng)建
下面的代碼說明了Counter類創(chuàng)建的四種方法:
Counter類的創(chuàng)建
>>> c = Counter() # 創(chuàng)建一個空的Counter類
>>> c = Counter('gallahad') # 從一個可iterable對象(list、tuple作彤、dict膘魄、字符串等)創(chuàng)建
>>> c = Counter({'a': 4, 'b': 2}) # 從一個字典對象創(chuàng)建
>>> c = Counter(a=4, b=2) # 從一組鍵值對創(chuàng)建
計數(shù)值的訪問與缺失的鍵
當所訪問的鍵不存在時乌逐,返回0,而不是KeyError创葡;否則返回它的計數(shù)浙踢。
計數(shù)值的訪問
>>> c = Counter("abcdefgab")
>>> c["a"]
2
>>> c["c"]
1
>>> c["h"]
0
計數(shù)器的更新(update和subtract)
可以使用一個iterable對象或者另一個Counter對象來更新鍵值。
計數(shù)器的更新包括增加和減少兩種灿渴。其中洛波,增加使用update()方法:
計數(shù)器的更新(update)
>>> c = Counter('which')
>>> c.update('witch') # 使用另一個iterable對象更新
>>> c['h']
3
>>> d = Counter('watch')
>>> c.update(d) # 使用另一個Counter對象更新
>>> c['h']
4
減少則使用subtract()方法:
計數(shù)器的更新(subtract)
>>> c = Counter('which')
>>> c.subtract('witch') # 使用另一個iterable對象更新
>>> c['h']
1
>>> d = Counter('watch')
>>> c.subtract(d) # 使用另一個Counter對象更新
>>> c['a']
-1
鍵的修改和刪除
當計數(shù)值為0時,并不意味著元素被刪除骚露,刪除元素應(yīng)當使用del蹬挤。
鍵的刪除
>>> c = Counter("abcdcba")
>>> c
Counter({'a': 2, 'c': 2, 'b': 2, 'd': 1})
>>> c["b"] = 0
>>> c
Counter({'a': 2, 'c': 2, 'd': 1, 'b': 0})
>>> del c["a"]
>>> c
Counter({'c': 2, 'b': 2, 'd': 1})
elements()
返回一個迭代器。元素被重復(fù)了多少次棘幸,在該迭代器中就包含多少個該元素焰扳。元素排列無確定順序,個數(shù)小于1的元素不被包含误续。
elements()方法
>>> c = Counter(a=4, b=2, c=0, d=-2)
>>> list(c.elements())
['a', 'a', 'a', 'a', 'b', 'b']
most_common([n])
返回一個TopN列表吨悍。如果n沒有被指定,則返回所有元素蹋嵌。當多個元素計數(shù)值相同時育瓜,排列是無確定順序的。
most_common()方法
>>> c = Counter('abracadabra')
>>> c.most_common()
[('a', 5), ('r', 2), ('b', 2), ('c', 1), ('d', 1)]
>>> c.most_common(3)
[('a', 5), ('r', 2), ('b', 2)]
淺拷貝copy
淺拷貝copy
>>> c = Counter("abcdcba")
>>> c
Counter({'a': 2, 'c': 2, 'b': 2, 'd': 1})
>>> d = c.copy()
>>> d
Counter({'a': 2, 'c': 2, 'b': 2, 'd': 1})