經常使用模塊-08collections模塊

在內置數據類型(dict、list、set、tuple)的基礎上,collections模塊還提供了幾個額外的數據類型:Counter、deque、defaultdict、namedtuple和OrderedDict等。html

  • 1.namedtuple: 生成可使用名字來訪問元素內容的tuple
  • 2.deque: 雙端隊列,能夠快速的從另一側追加和推出對象
  • 3.Counter: 計數器,主要用來計數
  • 4.OrderedDict: 有序字典
  • 5.defaultdict: 帶有默認值的字典

namedtuple(具名元組)

咱們知道tuple能夠表示不變集合,例如,一個點的二維座標就能夠表示成:python

p = (1, 2)

可是,看到(1, 2),很難看出這個tuple是用來表示一個座標的。app

這時,namedtuple就派上了用場:code

>>> from collections import namedtuple
>>> Point = namedtuple('Point', ['x', 'y'])
>>> p = Point(1, 2)
>>> p.x
1
>>> p.y
2

用具名元組來記錄一個城市的信息htm

>>> from collections import namedtuple
>>> City = namedtuple('City', 'name country population coordinates')  # 第一個是類名,第二個是類的各個字段的名字。後者能夠是由數個字符串組成的可迭代對象,或者是由空格分隔開的字段名組成的字符串
>>> tokyo = City('Tokyo', 'JP', 36.933, (35.689722, 139.691667)) 
>>> tokyo
City(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'

相似的,若是要用座標和半徑表示一個圓,也能夠用namedtuple定義:對象

#namedtuple('名稱', [屬性list]):
Circle = namedtuple('Circle', ['x', 'y', 'r'])


deque

使用list存儲數據時,按索引訪問元素很快,可是插入和刪除元素就很慢了,由於list是線性存儲,數據量大的時候,插入和刪除效率很低。blog

deque是爲了高效實現插入和刪除操做的雙向列表,適合用於隊列和棧:排序

>>> from collections import deque
>>> q = deque(['a', 'b', 'c'])
>>> q.append('x')
>>> q.appendleft('y')
>>> q
deque(['y', 'a', 'b', 'c', 'x'])

deque除了實現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的值中。

原生字典解決方法

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]

defaultdict字典解決方法

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類的目的是用來跟蹤值出現的次數。它是一個無序的容器類型,以字典的鍵值對形式存儲,其中元素做爲key,其計數做爲value。計數值能夠是任意的Interger(包括0和負數)。Counter類和其餘語言的bags或multisets很類似。

c = Counter('abcdeabcdabcaba')
print c

輸出:Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1})
參考文獻:
https://www.cnblogs.com/Dominic-Ji/articles/11109089.html
https://www.cnblogs.com/Dominic-Ji/articles/11109067.html#_label15

相關文章
相關標籤/搜索