標(biāo)準(zhǔn)庫(kù) Collections 中 4 個(gè)常用的數(shù)據(jù)結(jié)構(gòu)
collections 庫(kù)是標(biāo)準(zhǔn)庫(kù)的一部分,里面有很多數(shù)據(jù)結(jié)構(gòu),在列表、字典、元組的基礎(chǔ)上做了很多修改和提升。
今天就來(lái)說(shuō)說(shuō)最有用的幾個(gè)。
1、deque
它實(shí)現(xiàn)了兩端都可以操作的隊(duì)列,相當(dāng)于雙端隊(duì)列,與可以指定最多存儲(chǔ)多少個(gè)元素,與 Python 的基本數(shù)據(jù)類型列表很相似。
- from collections import deque
- a = deque(maxlen=3)
上述代碼定義了大小為 3 的雙端隊(duì)列,當(dāng)你插入第 4 個(gè)元素時(shí),隊(duì)列的第一個(gè)元素會(huì)被刪除。
- a = deque(maxlen=3)
- a.append(1) # a = [1]
- a.append(2) # a = [1, 2]
- a.append(3) # a = [1, 2, 3] FULL
- a.append(4) # a = [2,3,4]
因?yàn)檫@是一個(gè)雙端隊(duì)列,你可以在隊(duì)列的首位插入元素,也可以在首尾刪除元素,它們的時(shí)間復(fù)雜度都是 O(1):
- append(x) 在隊(duì)列尾部插入 x
- appendleft(x) 在隊(duì)列頭部插入 x
- pop() 在隊(duì)列尾部刪除一個(gè)元素,并返回
- popleft() 在隊(duì)列頭部刪除一個(gè)元素,并返回
- a = deque(maxlen = 10)
- a.append(1) # a = [1]
- a.append(2) # a = [1, 2] 在隊(duì)列尾部插入 2
- a.appendleft(3)# a = [3, 1, 2] 在隊(duì)列頭部插入 3
- x = a.pop() # a = [3, 1], x = 2 刪除隊(duì)列尾部元素 2
- y = a.popleft() # a = [1], y = 3 刪除隊(duì)列頭部元素 3
2、namedtuple
這個(gè)庫(kù)提供了命名的元組,可以通過(guò)指定的名稱來(lái)訪問(wèn),例如:
- from collections import namedtuple
- Point = namedtuple("Point", ['x','y','z'])
- p = Point(3,4,5)
- print(p.x, p.y, p.z) #Output: 3, 4, 5
namedtuple 函數(shù)把第一個(gè)參數(shù)作為新元組的名稱,第二個(gè)參數(shù)就是元組內(nèi)元素的名稱映射,可以是一個(gè)字符串列表,也可以是空格或逗號(hào)分割的字符串。
- Point = namedtuple("Point", "x y z")
- Point = namedtuple("Point", "x,y,z")
也可以這樣初始化,非常靈活:
- p1 = Point(3,4,5)
- p2 = Point(x=3, y=4, z=5)
- p3 = Point._make([3,4,5])
還可以使用 namedtuple 來(lái)設(shè)置默認(rèn)值:
- PointDef = namedtuple("PointDef", "x, y, z", defaults = [0,0,0])
- p = PointDef(x=1) # p is (1,0,0)
如果你定義了三個(gè)名稱,卻提供了兩個(gè)默認(rèn)值,那么只有最后兩個(gè)會(huì)被賦予默認(rèn)值:
- Point = namedtuple("Point", "x y z",defaults ="[0, 0])
- print(Point._field_defaults)
- # output: {“y”: 0, “z”: 0}
3、Counter
計(jì)數(shù)器 Counter 非常有用,尤其當(dāng)你需要統(tǒng)計(jì)列表或可迭代對(duì)象中元素的數(shù)量時(shí):
- from collections import Counter
- c = Counter(“aaabbccdaaa”)
- print(c)
- #Output: Counter({'a': 6, 'b': 2, 'c': 2, 'd': 1})
還可以方便的統(tǒng)計(jì)頻率前幾大,比如統(tǒng)計(jì)出現(xiàn)頻率最高的兩個(gè)元素:
- print(c.most_common(2))
- #output: [('a', 6), ('b', 2)]
還可以動(dòng)態(tài)增刪字符串,然后統(tǒng)計(jì):
- c = Counter("abbc") # {"a":1, "b":2, "c":1}
- c.update("bccd") # {"a":1, "b":3, "c":3, "d":1}
- c.subtract("bbc") # {"a":1, "b":1, "c":2, "d":1}
4、defaultdict
defaultdict 和 dict 差不多,但是可以提供 dict 的 values 的默認(rèn)數(shù)據(jù)類型,比如:
- from collections import defaultdict
- toAdd =[("key1", 3), ("key2", 5), ("key3", 6), ("key2", 7)]
- d = defaultdict(list)
- for key, val in toAdd:
- d[key].append(val)
- print(d) # {"key1":[3], "key2":[5, 7], "key3":[6]}
如果你用 dict,可能要這樣寫:
- d = dict()
- for key, val in toAdd:
- if key in d:
- d[key].append(val)
- else:
- d[key] = [val]
或者是這樣的:
- d = dict()
- for key, val in toAdd:
- d.setdefault(key, []).append(val)
總之,defaultdict 是簡(jiǎn)單和快捷的。