collections的常用類型有:
計數器(Counter)
雙向隊列(deque)
默認字典(defaultdict)
有序字典(OrderedDict)
可命名元組(namedtuple)
使用以上類型時需要導入模塊 from collections import *
1. Counter
Counter 作爲字典(dict)的一個子類用來進行hashtable計數,將元素進行數量統計、計數後返回一個字典,鍵值爲元素:值爲元素個數
- s = 'abcbcaccbbad'
- l = ['a','b','c','c','a','b','b']
- d = {'2': 3, '3': 2, '17': 2}
- # Counter 獲取各元素的個數,返回字典
- print(Counter(s)) # Counter({'c': 4, 'b': 4, 'a': 3})
- print(Counter(l)) # Counter({'b': 3, 'a': 2, 'c': 2})
- print(Counter(d)) # Counter({3: 3, 2: 2, 17: 1})
most_common
- # most_common(int) 按照元素出現的次數進行從高到低的排序,返回前int個元素的字典
- m1 = Counter(s)
- print(m1) # Counter({'c': 4, 'b': 4, 'a': 3, 'd': 1})
- print(m1.most_common(3)) # [('c', 4), ('b', 4), ('a', 3)]
elements
- # elements 返回經過計數器Counter後的元素,返回的是一個迭代器
- e1 = Counter(s)
- print(''.join(sorted(e1.elements()))) # aaabbbbcccc
- e2 = Counter(d)
- print(sorted(e2.elements())) # ['17', '17', '2', '2', '2', '3', '3'] 字典返回value個key
update
- # update 和set集合的update一樣,對集合進行並集更新
- u1 = Counter(s)
- u1.update('123a')
- print(u1) # Counter({'a': 4, 'c': 4, 'b': 4, '1': 1, '3': 1, '2': 1})
substract
- # substract 和update類似,只是update是做加法,substract做減法,從另一個集合中減去本集合的元素,
- sub1 = 'which'
- sub2 = 'whatw'
- subset = Counter(sub1)
- print(subset) # Counter({'h': 2, 'i': 1, 'c': 1, 'w': 1})
- subset.subtract(Counter(sub2))
- print(subset) # Counter({'c': 1, 'i': 1, 'h': 1, 'a': -1, 't': -1, 'w': -1}) sub1中的h變爲2,sub2中h爲1,減完以後爲1
iteritems
iterkeys
itervalues
2.deque
deque常用方法:
deque
- str1 = 'abc123cd'
- dq = deque(str1)
- print(dq) # deque(['a', 'b', 'c', '1', '2', '3', 'c', 'd'])
append
appendleft
- dq = deque('abc123')
- dq.append('right')
- dq.appendleft('left')
- print(dq) # deque(['left', 'a', 'b', 'c', '1', '2', '3', 'right'])
clear
clear 清空隊列中的所有元素count
extend
extendleft
- dq = deque('abc123')
- dq.extend({1:10,2:20})
- dq.extendleft('L')
- print(dq) # deque(['L', 'a', 'b', 'c', '1', '2', '3', 1, 2])
pop
popleft
popleft 移除並且返回隊列左邊的元素remove
reverse
reverse 隊列的所有元素進行反轉rotate
rotate(n) 對隊列的數進行移動,若n<0,則往左移動即將左邊的第一個移動到最後,移動n次,n>0 往右移動- dq = deque([1,2,3,4,5])
- dq.rotate(-1) # 左移,1往左移動一位到5後面
- print(dq)
3.defaultdict
- dic = collections.defaultdict(dict)
- dic['k1'].update({'k2':'aaa'})
- print(dic)
我看看一下傳統的字典類型
- b = dict()
- b['k1'].append('2')
- # TypeError: 'type' object is not iterable
4.OrderedDict
OrderDict 叫做有序字典,也是字典類型(dict)的一個子類,是對字典的一個補充。 前面我們說過,字典類型是一個無序的集合,如果要想將一個傳統的字典類型進行排序一般會怎麼做了,我們可能會將字典的鍵值取出來做排序後在根據鍵值來進行有序的輸出,我們看下面的一個例子:- # 定義傳統字典
- dic1 = dict()
- # 按順序添加字典內容
- dic1['a'] = '123'
- dic1['b'] = 'jjj'
- dic1['c'] = '394'
- dic1['d'] = '999'
- print(dic1) # 結果: {'a': '123', 'c': '394', 'b': 'jjj', 'd': '999'}
- # 排序
- dic1_key_list = []
- for k in dic1.keys():
- dic1_key_list.append(k)
- dic1_key_list.sort()
- for key in dic1_key_list:
- print('dic1字典排序結果 %s:%s' %(key,dic1[key]))
以上爲定義傳統字典類型時的一個簡單排序過程。 如果我們定義一個有序字典時,將不用再如此麻煩, 字典順序將按照錄入順序進行排序且不會改變。
- # 定義有序字典
- dic2 = OrderedDict()
- dic2['a'] = '123'
- dic2['b'] = 'jjj'
- dic2['c'] = 'abc'
- dic2['d'] = '999'
- for k, v in dic2.iteritems():
- print('有序字典:%s:%s' %(k,v))
5.nametuple
標準的tuple類型使用數字索引來訪問元素,
- bob = ('Bob', 30, 'male')
- print('Representation:', bob)
- jane = ('Jane', 29, 'female')
- print('\nField by index:', jane[0])
- print('\nFields by index:')
- for p in [bob, jane]:
- print('%s is a %d year old %s' % p)
這種對於標準的元組訪問,我們需要知道元素對應下標索引值,但當元組的元素很多時,我們可能無法知道每個元素的具體索引值,這個時候就是可命名元組登場的時候了。
nametuple 的創建是由自己的類工廠nametuple()進行創建,而不是由標準的元組來進行實例化,通過nametuple()創建類的參數包括類名稱和一個包含元素名稱的字符串
- from collections import namedtuple
- #創建一個nametuplede 類,類名稱爲Person,並賦給變量P
- P = namedtuple('Person', 'name,age,gender')
- print('Type of Person:', type(P)) # Type of Person: <class 'type'>
- #通過Person類實例化一個對象bob
- bob = P(name='Bob', age=30, gender='male')
- print('\nRepresentation:', bob) # Representation: Person(name='Bob', age=30, gender='male')
- #通過Person類實例化一個對象jane
- jane = P(name='Jane', age=29, gender='female')
- print('\nField by name:', jane.name) # Field by name: Jane
- print('\nFields by index:')
- for p in [bob, jane]:
- print('%s is a %d year old %s' % p)
- # Fields by index:
- # Bob is a 30 year old male
- # Jane is a 29 year old female
通過上面的實例可以看出,我們通過nametuple()創建了一個Person的類,並複製給P變量,Person的類成員包括name,age,gender,並且順序已經定了,在實例化zhangsan這個對象的時候,對張三的屬性進行了定義。這樣我們在訪問zhangsan這個元組的時候就可以通過張三的屬性來複制(zhangsan.name、zhangsan.age等)。這樣就算這個元組有1000個元素我們都能通過元素的名稱來訪問而不用考慮元素的下標索引值。
非法的參數值
使用nametuple()來創建類的時候,傳遞的成員屬性參數名稱不能非法(不能爲系統參數名稱),且參數名稱不能重複,否則會報值錯誤
- # 參數字段的名稱非法,包含系統名稱class
- try:
- p = namedtuple('Person','age,name,class,gender')
- print(p._fields)
- except ValueError as err:
- print(err)
- # Type names and field names cannot be a keyword: 'class'
- # 類成員字段參數名稱重複 age
- try:
- p1 = namedtuple('Person','age,gender,name,age')
- print(p1._fields)
- except ValueError as err:
- print(err)
- # Encountered duplicate field name: 'age'
但是也有時候我們是無法控制的,如果參數的名稱來自外部,比如是通過讀取數據庫中的內容來傳遞的參數,此時我們無法手工的修改參數名稱,那該如何是好呢! 別擔心,只需要增加一個屬性就OK了,它就是rename
- # 參數字段的名稱非法,包含系統名稱class
- try:
- p = namedtuple('Person','age,name,class,gender',rename=True)
- print(p._fields)
- except ValueError as err:
- print(err)
- # ('age', 'name', '_2', 'gender')
- # 類成員字段參數名稱重複 age
- try:
- p1 = namedtuple('Person','age,gender,name,age',rename=True)
- print(p1._fields)
- except ValueError as err:
- print(err)
- # ('age', 'gender', 'name', '_3')