一、collections子產品簡介
官方文檔:https://docs.python.org/zh-cn/3.7/library/collections.html
collections是Python标準庫中自帶的一個資料結構常用子產品。這個子產品實作了特定目标的容器,以提供Python标準内建容器 dict , list , set , 和 tuple 的替代選擇。
對象 | 作用 |
namedtuple() | 建立命名元組子類的工廠函數 |
deque | 類似清單(list)的容器,實作了在兩端快速添加(append)和彈出(pop) |
ChainMap | 類似字典(dict)的容器類,将多個映射集合到一個視圖裡面 |
Counter | 字典的子類,提供了可哈希對象的計數功能 |
OrderedDict | 字典的子類,儲存了他們被添加的順序 |
defaultdict | 字典的子類,提供了一個工廠函數,為字典查詢提供一個預設值 |
UserDict | 封裝了字典對象,簡化了字典子類化 |
UserList | 封裝了清單對象,簡化了清單子類化 |
UserString | 封裝了字元串對象,簡化了字元串子類化 |
二、ChainMap對象
一個 ChainMap 将多個字典或者其他映射組合在一起,建立一個單獨的可更新的視圖。它通常比建立一個新字典和多次調用 update() 要快很多。 如果沒有 maps 被指定,就提供一個預設的空字典,這樣一個新鍊至少有一個映射。
底層映射被存儲在一個清單中。這個清單是公開的,可以通過 maps 屬性存取和更新。沒有其他的狀态。
搜尋查詢底層映射,直到一個鍵被找到。不同的是,寫、更新和删除隻操作第一個映射。
ChainMap 通過引用合并底層映射。是以,如果一個底層映射更新了,這些更改會反映到 ChainMap 。
支援所有常用字典方法。另外還有一個 maps 屬性(attribute),一個建立子上下文的方法(method), 一個存取它們首個映射的屬性(property)。
from collections import *
"""ChainMap對象"""
base_dic = {"name": "Python", "age": 28, "city": "Nanjing"}
new_dic = {"city": "Shanghai", "job": "tester", "sex": "man"}
last = {"money": 999}
# 擷取ChainMap對象的key清單,自動去重
print(list(ChainMap(base_dic, new_dic, last)))
# 擷取ChainMap對象的maps清單
print(ChainMap(base_dic, new_dic, last).maps)
'''
ChainMap({'name': 'Python', 'age': 28, 'city': 'Nanjing'}, {'city': 'Shanghai', 'job': 'tester', 'sex': 'man'}, {'money': 999})
['money', 'city', 'job', 'sex', 'name', 'age']
[{'name': 'Python', 'age': 28, 'city': 'Nanjing'}, {'city': 'Shanghai', 'job': 'tester', 'sex': 'man'}, {'money': 999}]
'''
三、Counter對象
一個 Counter 是一個 dict 的子類,用于計數可哈希對象。它是一個集合,元素像字典鍵(key)一樣存儲,它們的計數存儲為值。計數可以是任何整數值,包括0和負數。 Counter 類有點像其他語言中的 bags或multisets。
1.Counter計數功能
Counter對象類似于字典,形式為Counter({key1: value1, key2: value2}),其中value為對應key出現的次數;如果某個項缺失,會傳回0,而不是報出KeyError。
# Counter計數功能
w_list = ["php", "python", "go", "ruby", "python", "java", "go", "python", "c++"]
count = Counter(w_list)
# Counter對象類似于字典,value為對應key出現的數量
print(count) # Counter({'python': 3, 'go': 2, 'php': 1, 'ruby': 1, 'java': 1, 'c++': 1})
print(count.items()) # dict_items([('php', 1), ('python', 3), ('go', 2), ('ruby', 1), ('java', 1), ('c++', 1)])
print(count.keys()) # dict_keys(['php', 'python', 'go', 'ruby', 'java', 'c++'])
print(count.values()) # dict_values([1, 3, 2, 1, 1, 1])
# 如果某個項缺失,會傳回0,而不是報出KeyError
print(count["python"]) # 3 傳回該元素的數量
print(count["kotlin"]) # 0
2. most_common 清單排列順序
傳回一個清單,提供 n 個頻率最高的元素和計數。 如果沒提供 n ,或者是 None , most_common() 傳回計數器中的所有元素。相等個數的元素順序随機。
清單中的元素形式為二進制組,按照key數量從大到小排列,n表示清單截取的二進制組個數
w_list = ["php", "python", "go", "ruby", "python", "java", "go", "python", "c++"]
count = Counter(w_list)
# most_common
# 傳回一個清單,清單中的元素形式為二進制組,按照key數量從大到小排列,n表示清單截取的二進制組個數
print(count.most_common()) # [('python', 3), ('go', 2), ('php', 1), ('ruby', 1), ('java', 1), ('c++', 1)]
print(count.most_common(n=3)) # [('python', 3), ('go', 2), ('php', 1)]
print(count.most_common(n=2)) # [('python', 3), ('go', 2)]
3.update 更新可疊代對象清單
從 疊代對象 計數元素或者 從另一個 映射對象 (或計數器) 添加。 像 dict.update() 但是是加上,而不是替換。另外,疊代對象 應該是序列元素,而不是一個 (key, value) 對。
# update 更新可疊代對象清單
# 将一個可疊代對象清單的元素添加到另一個可疊代對象中
list_a = ["php", "python", "go", "python", "java", "go", "python"]
list_b = [1, "php", 3, 3, 88, 77, "python", 99]
c1 = Counter(list_a)
c2 = Counter(list_b)
print(c1) # Counter({'python': 3, 'go': 2, 'php': 1, 'java': 1})
print(c2) # Counter({3: 2, 1: 1, 'php': 1, 88: 1, 77: 1, 'python': 1, 99: 1})
# 将Counter對象c2中的元素添加到Counter對象c1中,存在重複元素、累加計算
c1.update(c2)
print(c1) # Counter({'python': 4, 'php': 2, 'go': 2, 3: 2, 'java': 1, 1: 1, 88: 1, 77: 1, 99: 1})
四、OrderedDict對象
有序詞典就像正常詞典一樣,但有一些與排序操作相關的額外功能。
'''OrderedDict對象'''
# OrderedDict有序字典
# 按照插入的順序來排列,字典不會因為key或value的值,再自動排序
od = OrderedDict()
od["k1"] = "tom"
od["k2"] = "lucy"
od["k3"] = "jerry"
print(od) # OrderedDict([('k1', 'tom'), ('k2', 'lucy'), ('k3', 'jerry')])
# 指定一個清單,把清單中的值,作為字典的key,生成一個字典
info = ["name", "age", "height", "weight"]
print(od.fromkeys(info)) # OrderedDict([('name', None), ('age', None), ('height', None), ('weight', None)])
print(od.fromkeys(info, 20)) # OrderedDict([('name', 20), ('age', 20), ('height', 20), ('weight', 20)])
1.popitem(last=True)
有序字典的 popitem() 方法移除并傳回一個 (key, value) 鍵值對。 如果 last 值為真,則按 LIFO 後進先出的順序傳回鍵值對,否則就按 FIFO 先進先出的順序傳回鍵值對。
od = OrderedDict()
od["k1"] = "tom"
od["k2"] = "lucy"
od["k3"] = "jerry"
# 先進先出-從開頭開始删除
od.popitem(last=False)
print(od) # OrderedDict([('k2', 'lucy'), ('k3', 'jerry')])
# 後進先出-從末尾開始删除
od.popitem(last=True)
print(od) # OrderedDict([('k1', 'tom'), ('k2', 'lucy')])
2.move_to_end(key, last=True)
将現有 key 移動到有序字典的任一端。 如果 last 為真值(預設)則将元素移至末尾;如果 last 為假值則将元素移至開頭。如果 key 不存在則會觸發 KeyError。
od = OrderedDict()
od["k1"] = "tom"
od["k2"] = "lucy"
od["k3"] = "jerry"
# 将指定key移動至末尾
od.move_to_end(last=True, key="k2")
print(od) # OrderedDict([('k1', 'tom'), ('k3', 'jerry'), ('k2', 'lucy')])
# 将指定key移動至開頭
od.move_to_end(last=False, key="k2")
print(od) # OrderedDict([('k2', 'lucy'), ('k1', 'tom'), ('k3', 'jerry')])
五、deque隊列
Deque子產品是Python标準庫collections中的一項,它提供了兩端都可以操作的序列,這意味着你可以在序列前後都執行添加或删除,并且可以限制隊列容量。
1.deque常用方法
方法 | 作用 |
append(x) | 添加x到最右端 |
appendleft(x) | 添加x到最左端 |
clear() | 移除所有元素,使其長度為0. |
copy() | 建立一份淺拷貝 |
count(x) | 計算deque中x元素的個數 |
extend(iterable) | 擴充deque的右側,向deque中添加iterable中的元素 |
extendleft(iterable) | 擴充deque的左側,向deque中添加iterable中的元素 |
index(x[, start[, stop]]) | 傳回 x 在 deque 中的位置(在索引 start 之後,索引 stop 之前)傳回第一個比對項,如果未找到則引發 ValueError |
insert(i, x) | 在位置 i 插入 x |
pop() | 移去并且傳回一個元素,deque 最右側的那一個。 如果沒有元素的話,就引發一個 IndexError。 |
popleft() | 移去并且傳回一個元素,deque 最左側的那一個。 如果沒有元素的話,就引發 IndexError。 |
remove(value) | 移除找到的第一個 value。 如果沒有的話就引發ValueError。 |
reverse() | 将deque逆序排列。傳回 None 。 |
rotate(n=1) | 向右循環移動 n 步。 如果 n 是負數,就向左循環。如果deque不是空的,向右循環移動一步就等價于 d.appendleft(d.pop()) , 向左循環一步就等價于 d.append(d.popleft()) 。 |
建立隊列
# 建立雙向隊列
cd = collections.deque()
添加元素
# append-向右邊添加元素
cd.append("python")
cd.append("java")
cd.append("c++")
print(cd) # deque(['python', 'java', 'c++'])
# appendleft-向左邊添加元素
cd.appendleft("php")
cd.appendleft("js")
print(cd) # deque(['js', 'php', 'python', 'java', 'c++'])
# insert-在指定位置插入元素
cd.insert(0, "000")
print(cd) # deque(['000', 'js', 'php', 'python', 'java', 'c++'])
擴充隊列
# extend-從隊列右邊擴充元素
cd.extend(["name", "age", "height"])
print(cd) # deque(['js', 'php', 'python', 'java', 'c++', 'name', 'age', 'height'])
# extend-從隊列左邊擴充元素
cd.extendleft(("kotlin", "golang"))
print(cd) # deque(['golang', 'kotlin', 'js', 'php', 'python', 'java', 'c++', 'name', 'age', 'height'])
查找元素索引位置
# index-查找某個元素的索引位置
print(cd.index("java")) # 6
删除隊列中的元素
# 删除隊列中的元素
# pop-從隊列右邊開始删除一個元素
cd.pop() # 'age'元素被删除
print(cd) # deque(['golang', 'kotlin', '000', 'js', 'php', 'python', 'java', 'c++', 'name', 'age'])
# popleft-從隊列左邊開始删除一個元素
cd.popleft() # '000'元素被删除
print(cd) # deque(['kotlin', '000', 'js', 'php', 'python', 'java', 'c++', 'name', 'age'])
# remove-删除指定元素
cd.remove("c++")
print(cd) # deque(['kotlin', '000', 'js', 'php', 'python', 'java', 'name', 'age'])
隊列反轉
# 隊列反轉
cd.reverse()
print(cd) # deque(['age', 'name', 'java', 'python', 'php', 'js', '000', 'kotlin'])
清空隊列
# 清空隊列
cd.clear()
print(cd) # deque([])
2.deque常用屬性
屬性 | 作用 |
maxlen | Deque的最大尺寸,如果沒有限定的話就是 None 。 |
限制deque長度
# maxlen-限制deque的長度,當deque長度超過限制時,另一邊的元素會自動删除
cf = collections.deque(maxlen=3)
# 從右邊添加,超長時自動删除左邊的元素
cf.append("python")
cf.append("java")
cf.append("c++")
cf.append("c") # 此時會自動删除左邊的元素"python"
print(cf) # deque(['java', 'c++', 'c'], maxlen=3)
# 從左邊添加,超長時自動删除右邊的元素
cf.appendleft("go") # 此時會自動删除右邊的元素"c"
print(cf) # deque(['go', 'java', 'c++'], maxlen=3)