Python系列之 - Collections

collections的常用類型有:

計數器(Counter)

雙向隊列(deque)

默認字典(defaultdict)

有序字典(OrderedDict)

可命名元組(namedtuple)

使用以上類型時需要導入模塊 from collections import *

1. Counter

Counter 作爲字典(dict)的一個子類用來進行hashtable計數,將元素進行數量統計、計數後返回一個字典,鍵值爲元素:值爲元素個數

[python] view plain copy
  1. s = 'abcbcaccbbad'  
  2. l = ['a','b','c','c','a','b','b']  
  3. d = {'2'3'3'2'17'2}  
  4. # Counter 獲取各元素的個數,返回字典  
  5. print(Counter(s))   # Counter({'c': 4, 'b': 4, 'a': 3})  
  6. print(Counter(l))   # Counter({'b': 3, 'a': 2, 'c': 2})  
  7. print(Counter(d))   # Counter({3: 3, 2: 2, 17: 1})  

most_common

[python] view plain copy
  1. # most_common(int) 按照元素出現的次數進行從高到低的排序,返回前int個元素的字典  
  2. m1 = Counter(s)  
  3. print(m1)                 # Counter({'c': 4, 'b': 4, 'a': 3, 'd': 1})  
  4. print(m1.most_common(3))  # [('c', 4), ('b', 4), ('a', 3)]  

elements

[python] view plain copy
  1. # elements 返回經過計數器Counter後的元素,返回的是一個迭代器  
  2. e1 = Counter(s)  
  3. print(''.join(sorted(e1.elements())))  # aaabbbbcccc  
  4. e2 = Counter(d)  
  5. print(sorted(e2.elements()))  # ['17', '17', '2', '2', '2', '3', '3'] 字典返回value個key  

update

[python] view plain copy
  1. # update 和set集合的update一樣,對集合進行並集更新  
  2. u1 = Counter(s)  
  3. u1.update('123a')  
  4. print(u1)  # Counter({'a': 4, 'c': 4, 'b': 4, '1': 1, '3': 1, '2': 1})  

substract

[python] view plain copy
  1. # substract 和update類似,只是update是做加法,substract做減法,從另一個集合中減去本集合的元素,  
  2. sub1 = 'which'  
  3. sub2 = 'whatw'  
  4. subset = Counter(sub1)  
  5. print(subset)   # Counter({'h': 2, 'i': 1, 'c': 1, 'w': 1})  
  6. subset.subtract(Counter(sub2))  
  7. print(subset)   # Counter({'c': 1, 'i': 1, 'h': 1, 'a': -1, 't': -1, 'w': -1}) sub1中的h變爲2,sub2中h爲1,減完以後爲1  

iteritems

與字典dict的items類似,返回由Counter生成的字典的所有item,只是在Counter中此方法返回的是一個迭代器,而不是列表

iterkeys

與字典dict的keys方法類似,返回由Counter生成的字典的所有key,只是在Counter中此方法返回的是一個迭代器,而不是列表

itervalues

與字典dict的values方法類似,返回由Counter生成的字典的所有value,只是在Counter中此方法返回的是一個迭代器,而不是列表

2.deque

deque 包含在文件_collections.py中,屬於高性能的數據結構(High performance data structures)之一.可以從兩端添加和刪除元素,常用的結構是它的簡化版

deque常用方法:

deque

[python] view plain copy
  1. str1 = 'abc123cd'  
  2. dq = deque(str1)  
  3. print(dq)        # deque(['a', 'b', 'c', '1', '2', '3', 'c', 'd'])  

append

隊列右邊添加元素

appendleft

隊列左邊添加元素
[python] view plain copy
  1. dq = deque('abc123')  
  2. dq.append('right')  
  3. dq.appendleft('left')  
  4. print(dq) # deque(['left', 'a', 'b', 'c', '1', '2', '3', 'right'])  

clear

clear 清空隊列中的所有元素

count

count(value)  返回隊列中包含value的個數,結果類型爲 integer

extend

extend 隊列右邊擴展,可以是列表、元組或字典,如果是字典則將字典的key加入到deque

extendleft

extendleft  同extend, 在左邊擴展
[python] view plain copy
  1. dq = deque('abc123')  
  2. dq.extend({1:10,2:20})  
  3. dq.extendleft('L')  
  4. print(dq) # deque(['L', 'a', 'b', 'c', '1', '2', '3', 1, 2])  

pop

pop  移除並且返回隊列右邊的元素

popleft

popleft 移除並且返回隊列左邊的元素

remove

remove(value) 移除隊列第一個出現的元素(從左往右開始的第一次出現的元素value)

reverse

reverse  隊列的所有元素進行反轉

rotate

rotate(n) 對隊列的數進行移動,若n<0,則往左移動即將左邊的第一個移動到最後,移動n次,n>0 往右移動
[python] view plain copy
  1. dq = deque([1,2,3,4,5])  
  2. dq.rotate(-1# 左移,1往左移動一位到5後面  
  3. print(dq)  

3.defaultdict

默認字典,是字典的一個子類,繼承有字典的方法和屬性,默認字典在進行定義初始化的時候可以指定字典值得默認類型:
[python] view plain copy
  1. dic = collections.defaultdict(dict)  
  2. dic['k1'].update({'k2':'aaa'})  
  3. print(dic)  
我們看上面的例子,字典dic在定義的時候就定義好了值爲字典類型,雖然現在字典中還沒有鍵值 k1,但仍然可以執行字典的update方法. 這種操作方式在傳統的字典類型中是無法實現的,必須賦值以後才能進行值得更新操作,否則會報錯。
我看看一下傳統的字典類型
[python] view plain copy
  1. b = dict()  
  2. b['k1'].append('2')  
  3. # TypeError: 'type' object is not iterable  

4.OrderedDict 

OrderDict 叫做有序字典,也是字典類型(dict)的一個子類,是對字典的一個補充。 前面我們說過,字典類型是一個無序的集合,如果要想將一個傳統的字典類型進行排序一般會怎麼做了,我們可能會將字典的鍵值取出來做排序後在根據鍵值來進行有序的輸出,我們看下面的一個例子:
[python] view plain copy
  1. # 定義傳統字典  
  2. dic1 = dict()  
  3. # 按順序添加字典內容  
  4. dic1['a'] = '123'  
  5. dic1['b'] = 'jjj'  
  6. dic1['c'] = '394'  
  7. dic1['d'] = '999'  
  8. print(dic1)    # 結果: {'a': '123', 'c': '394', 'b': 'jjj', 'd': '999'}  
  9. # 排序  
  10. dic1_key_list = []  
  11. for k in dic1.keys():  
  12.     dic1_key_list.append(k)  
  13. dic1_key_list.sort()  
  14. for key in dic1_key_list:  
  15.     print('dic1字典排序結果 %s:%s' %(key,dic1[key]))  

以上爲定義傳統字典類型時的一個簡單排序過程。 如果我們定義一個有序字典時,將不用再如此麻煩, 字典順序將按照錄入順序進行排序且不會改變。
[python] view plain copy
  1. # 定義有序字典  
  2. dic2 = OrderedDict()  
  3. dic2['a'] = '123'  
  4. dic2['b'] = 'jjj'  
  5. dic2['c'] = 'abc'  
  6. dic2['d'] = '999'  
  7. for k, v in dic2.iteritems():  
  8.     print('有序字典:%s:%s' %(k,v))  

 

5.nametuple

標準的tuple類型使用數字索引來訪問元素,

[python] view plain copy
  1. bob = ('Bob'30'male')  
  2. print('Representation:', bob)  
  3.   
  4. jane = ('Jane'29'female')  
  5. print('\nField by index:', jane[0])  
  6.   
  7. print('\nFields by index:')  
  8. for p in [bob, jane]:  
  9.     print('%s is a %d year old %s' % p)  

這種對於標準的元組訪問,我們需要知道元素對應下標索引值,但當元組的元素很多時,我們可能無法知道每個元素的具體索引值,這個時候就是可命名元組登場的時候了。

nametuple 的創建是由自己的類工廠nametuple()進行創建,而不是由標準的元組來進行實例化,通過nametuple()創建類的參數包括類名稱和一個包含元素名稱的字符串

[python] view plain copy
  1. from collections import namedtuple  
  2.   
  3. #創建一個nametuplede 類,類名稱爲Person,並賦給變量P  
  4. P = namedtuple('Person''name,age,gender')  
  5. print('Type of Person:', type(P))  # Type of Person: <class 'type'>  
  6.   
  7. #通過Person類實例化一個對象bob  
  8. bob = P(name='Bob', age=30, gender='male')  
  9. print('\nRepresentation:', bob)  # Representation: Person(name='Bob', age=30, gender='male')  
  10.   
  11. #通過Person類實例化一個對象jane  
  12. jane = P(name='Jane', age=29, gender='female')  
  13. print('\nField by name:', jane.name)  # Field by name: Jane  
  14.   
  15. print('\nFields by index:')  
  16. for p in [bob, jane]:  
  17.     print('%s is a %d year old %s' % p)  
  18. # Fields by index:  
  19. # Bob is a 30 year old male  
  20. # Jane is a 29 year old female  

通過上面的實例可以看出,我們通過nametuple()創建了一個Person的類,並複製給P變量,Person的類成員包括name,age,gender,並且順序已經定了,在實例化zhangsan這個對象的時候,對張三的屬性進行了定義。這樣我們在訪問zhangsan這個元組的時候就可以通過張三的屬性來複制(zhangsan.name、zhangsan.age等)。這樣就算這個元組有1000個元素我們都能通過元素的名稱來訪問而不用考慮元素的下標索引值。

非法的參數值

使用nametuple()來創建類的時候,傳遞的成員屬性參數名稱不能非法(不能爲系統參數名稱),且參數名稱不能重複,否則會報值錯誤

[python] view plain copy
  1. # 參數字段的名稱非法,包含系統名稱class  
  2. try:  
  3.     p = namedtuple('Person','age,name,class,gender')  
  4.     print(p._fields)  
  5. except ValueError as err:  
  6.     print(err)  
  7.   
  8. # Type names and field names cannot be a keyword: 'class'  
  9.   
  10. # 類成員字段參數名稱重複 age  
  11. try:  
  12.     p1 = namedtuple('Person','age,gender,name,age')  
  13.     print(p1._fields)  
  14. except ValueError as err:  
  15.     print(err)  
  16. # Encountered duplicate field name: 'age'  

但是也有時候我們是無法控制的,如果參數的名稱來自外部,比如是通過讀取數據庫中的內容來傳遞的參數,此時我們無法手工的修改參數名稱,那該如何是好呢! 別擔心,只需要增加一個屬性就OK了,它就是rename

[python] view plain copy
  1. # 參數字段的名稱非法,包含系統名稱class  
  2. try:  
  3.     p = namedtuple('Person','age,name,class,gender',rename=True)  
  4.     print(p._fields)  
  5. except ValueError as err:  
  6.     print(err)  
  7.   
  8. # ('age', 'name', '_2', 'gender')  
  9.   
  10. # 類成員字段參數名稱重複 age  
  11. try:  
  12.     p1 = namedtuple('Person','age,gender,name,age',rename=True)  
  13.     print(p1._fields)  
  14. except ValueError as err:  
  15.     print(err)  
  16. # ('age', 'gender', 'name', '_3')  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章