1. 程式人生 > 實用技巧 >Python演算法黑科技collection模組

Python演算法黑科技collection模組

collection就是基於python基本資料型別併為之添加了一些新的功能,也可以說是提供了幾種高階資料型別,在。

  這個模組實現了特定目標的容器,以提供Python標準內建容器 dict , list , set , 和 tuple 的替代選擇。

功能 註釋
deque 類似列表(list)的容器,實現了在兩端快速新增(append)和彈出(pop)
ChainMap 類似字典(dict)的容器類,將多個對映集合到一個視圖裡面
Counter 字典的子類,提供了可雜湊物件的計數功能
OrderedDict 字典的子類,儲存了他們被新增的順序
defaultdict 字典的子類,提供了一個工廠函式,為字典查詢提供一個預設值
namedtuple 建立命名元組子類的工廠函式

deque雙端佇列

  deque本質上就是實現了資料結構中佇列的升級版,雙端佇列可以高效的實現插入和刪除的雙向列表,適用於佇列和棧。

雙端佇列支援執行緒安全,在雙端佇列的任何一端執行新增和刪除操作,它們的記憶體效率幾乎相同(時間複雜度為O(1))。

from collections import deque

q= deque(['a','b','c'])
q.append('1')
q.appendleft('2')

print(q)
#deque(['2', 'a', 'b', 'c', '1'])

ChainMap

  這個功能的目的是為了將多個對映快速的連結到一起,這樣它們就可以作為一個單元處理。它通常比建立一個新字典和多次呼叫 update() 要快很多,因為我們這麼做的話要新建一個數據結構,這樣的話對空間和時間上的浪費都是不小得。

1、可以用來合併兩個或者更多個字典,當查詢的時候,從前往後依次查詢,若該多個字典當中有相同的key時,只會顯示第一個字典相對應的value

2、當對ChainMap進行修改的時候總是隻會對第一個字典進行修改

3、new_child()方法實質上是在列表的第一個元素前放入一個字典,預設是{},而parents是去掉了列表開頭的元素

from collections import ChainMap
a = {"x":1, "z":3}
b = {"y":2, "z":4}
c = ChainMap(a,b)
print(c)
print("x: %d, y: %d, z: %d" % (c["x"], c["y"], c["z"]))
print("x: %d, y: %d, z: %d, z: %d " % (c["x"], c["y"], c["z"], c["z"]))
輸出:
ChainMap({'x': 1, 'z': 3}, {'y': 2, 'z': 4})
x: 1, y: 2, z: 3
x: 1, y: 2, z: 3, z: 3       

Counter計數器

  Counter是對字典型別的補充,用於追蹤值出現的次數,它繼承於字典,用於計數可雜湊的物件,計數的數值可以是正整數、負整數和零。

from collections import Counter
c = Counter('asdadiuhiuchizuha')
print(c)

輸出:Counter({'a': 3, 'i': 3, 'u': 3, 'h': 3, 'd': 2, 's': 1, 'c': 1, 'z': 1})

OrderedDict有序字典

  OrderedDict和一般的dict類似,但是還具有記憶字典中儲存的key的插入順序。但是現在OrderDict可能用處不大了,因為從Python 3.7開始,一般的dict也具有這個特性。

  該功能按照需求使用,若最重要的是排序操作,而空間效率、迭代效率以及更新字典的效能是次要的,則使用該功能,否則用dict即可

  OrderedDict可以處理頻繁的需要重排的操作,適合於Track最近的操作;

  判斷兩個OrderedDict是否相等同時要求順序也相同;

  OrderedDictpopitem(last=True)中可以通過last引數控制pop哪一端的元素;

  OrderedDictmove_to_end(key, last=True)可以高效的將元素移至末尾;


defaultdict預設字典

  關於defaultdict,我們可以先看一下dict中一個類似功能的函式setdefault(k, d=None):

d = {}
s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]

for k, v in s:
    d.setdefault(k, []).append(v)

sorted(d.items())
[out]:[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]

  在上述程式碼中,setdefault(k, d=[])一句話相當於做了兩件事情:一是獲取key為k的的value,二是若該key不存在則設定其值為[]。即,d.get(k, [])以及如果key不存在就設定d[k] = []。現在再回到defaultdictdefaultdict([default_factory[, ...]]),構造方法中default_factory預設是Nonedefaultdictdict的一個subclass,它重寫了一個__missing__方法以及擁有一個default_factory屬性。

  • __missing__(key)

    • 該方法在當key不存在時才會且僅被__getitem__()呼叫,所以當使用dict.get()方法獲取一個不存在的鍵值時,返回結果為None,而不是使用default_factory

    • default_factoryNone時,索引一個不存在的key會引發KeyError異常;

    • default_factory不為None時,索引一個不存在的key則使用default_factory進行初始化並返回值

      from collections import defaultdict
      
      [in]:d2 = defaultdict(int ,a=1, b=2)
      [in]:d2['c']
      [out]:0
      
      [in]:d2 = defaultdict(int ,a=1, b=2)
      [in]:d2.get('c')
      [out]:None
          
      [in]:d2
      [out]:defaultdict(int, {'a': 1, 'b': 2})
      
      [in]:d1 = defaultdict(a=1, b=2)
      [in]:d1['c']
      [out]:KeyError: 'c'
      
  • default_factory

    該屬性在上述 __missing__()函式中使用,由建構函式中的default_factory初始化,預設為None

    因此,上述例子可以使用defaultdict來實現如下:

    s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
    d = defaultdict(list)
    for k, v in s:
        d[k].append(v)
    
    sorted(d.items())
    [out]:[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
    

namedtuple具名元組

  見名知意,就是具有名字的元組,因為我們知道,元組是不可變型別,而且只能靠索引獲得值,這裡用具名元組目的就是讓元組有名字方便查詢

from collections import  namedtuple
# namedtuple('名稱', [屬性list]):
point = namedtuple('p',['x','y'])
p = point(1,2)
print(p.x) #1
print(p.y) #2

  這個可以用在函式返回多值的時候,因為是元組,這樣寫見名知意,為程式碼可讀性提供了便利!