標籤:索引 get 查看 **kwargs 出現 pre 而且 列表 訪問
namedtuple
from collections import namedtuplegirl = namedtuple("aaa", ["name", "age", "gender", "anime"])girl = girl(name="satori", age=18, gender="f", anime="東方地靈殿")print(girl) # aaa(name=‘satori‘, age=18, gender=‘f‘, anime=‘東方地靈殿‘)print(girl.name) # satoriprint(girl.age) # 18print(girl.anime) # 東方地靈殿
from collections import namedtuplegirl = namedtuple("aaa", ["name", "age", "gender", "anime"])t = ("satori", 18, "f", "東方地靈殿")# 也可以不指定列名,直接按照順序傳入參數girl = girl(*t)print(girl) # aaa(name=‘satori‘, age=18, gender=‘f‘, anime=‘東方地靈殿‘)# 也可以傳入一個字典d = { "name": "satori", "age": 18, "gender": "f", "anime": "東方地靈殿"}girl = namedtuple("aaa", ["name", "age", "gender", "anime"])girl = girl(**d)print(girl) # aaa(name=‘satori‘, age=18, gender=‘f‘, anime=‘東方地靈殿‘)
defaultdict
# 如果是一般的字典的話,當我們想要統計次數的話l = ["a", "b", "a", "c", "c", "a", "a"]d = {}for i in l: if i not in d: d[i] = 1 else: d[i] += 1print(d) # {‘a‘: 4, ‘b‘: 1, ‘c‘: 2}# 這段代碼有什麼問題呢?其實沒什麼問題,就是當資料量大了時候,會很麻煩# 這時候defaultdict就出現了
from collections import defaultdict# 裡面要傳入一個可調用的對象,什麼意思呢?default_dict = defaultdict(int)# 當我訪問一個不存在的值print(default_dict["a"]) # 0default_dict = defaultdict(str)print(default_dict["a"]) # ""default_dict = defaultdict(tuple)print(default_dict["a"]) # ()default_dict = defaultdict(list)print(default_dict["a"]) # []default_dict = defaultdict(set)print(default_dict["a"]) # set()default_dict = defaultdict(dict)print(default_dict["a"]) # {}# 看到這應該就明白了,如果訪問一個不存在的key,那麼會首先建立該key,然後value對應defaultdict裡面傳入的類型的初始值l = ["a", "b", "a", "c", "c", "a", "a"]default_dict = defaultdict(int)for i in l: # 首先沒有key會建立,然後value初始化為0,然後執行+=1 # 注意:在沒有相應的key的時候,這行代碼錶示執行兩個步驟 # 先執行default_dict[i] = 0 # 然後default_dict[i] += 1 # 當key存在的時候,直接執行+=1操作 default_dict[i] += 1 # 這樣操作就大大簡便了 # 普通的列表的話,也可以使用setdefault,但是還是這個簡單print(default_dict) # defaultdict(<class ‘int‘>, {‘a‘: 4, ‘b‘: 1, ‘c‘: 2})print(type(default_dict)) # <class ‘collections.defaultdict‘># 也可以直接轉化為字典print(dict(default_dict)) # {‘a‘: 4, ‘b‘: 1, ‘c‘: 2}# 那麼defaultdict是如何?的呢?主要用到了__missing__這個魔法函數class A(dict): def __init__(self, **kwargs): super().__init__(**kwargs) def __missing__(self, key): return key# 必須繼承dicta = A(name="satori", age=19)# 可以看到a中只有name和age這兩個屬性print(a["name"]) # satoriprint(a["age"]) # 19# 當我訪問一個不存在的屬性print(a["mmp"]) # mmp# __missing__的作用就在於此,當然這個魔法方法只能用在dict的子類當中。要是普通的類,可以用__getattr__# 來類比一下defaultdictclass Satoridict(dict): def __init__(self, **kwargs): super().__init__(**kwargs) def __missing__(self, key): self[key] = 0 return self[key] def __getitem__(self, item): # return self[item],不可以return self[item] # 為什嗎?因為調用__getitem__,return self[item],然後又執行__getitem__,又return self[item],從而無限遞迴 # 那麼怎麼擷取值呢?return item的話會不報錯,但擷取的只是key,得不到value啊 # 我們可以調用父類的方法 value = super().__getitem__(item) # 會先執行__getitem__方法,在執行super().__getitem__的時候 # 如果沒有__missing__方法,會報錯,KeyError。 # 如果有__missing__那麼會執行__missing__方法,設定self[key]=0,返回self[key] return valuesatori = Satoridict(name="Satori", age=18, gender="f")print(satori["name"]) # Satoriprint(satori["age"]) # 18# 訪問一個不存在的值print(satori["aaa"]) # 0
deque
# 先來看看queuefrom queue import Queueq = Queue()q.put(1)q.put(2)q.put(3)print(q.get()) # 1print(q.get()) # 2print(q.get()) # 3# 預設的隊列,只能append,而且取的時候只能從頭開始取
from collections import deque# 雙端隊列,可以從兩段插入,也可以從兩段取值q = deque(("a", "b", "c"))q.append(1)q.appendleft(2)print(q) # deque([2, ‘a‘, ‘b‘, ‘c‘, 1])# 也可以通過索引取值print(q[1]) # a# 通過pop取值print(q.pop()) # 1print(q.popleft())print(q) # deque([‘a‘, ‘b‘, ‘c‘]), 可以看到和list一樣,pop之後q的元素減少了# deque的絕大部分api和list是一致的,只是deque多了appendleft,popleft,extendleft# 對list如何操作,對deque也如何操作就行了,會list就會deque,這裡的一些方法不贅述了# 最重要的一點,deque和queue一樣也是安全執行緒的,是由GIL這把超級大鎖保護的# 和queue相比,deque還有一個重要的地方import queueq1 = queue.Queue(maxsize=3)q2 = deque(maxlen=3)# 當q1塞滿三個元素之後,再想塞第四個就塞不進去為了# 但是對q2來說,塞多少個都沒問題,我們來列印一下q2.append(1)q2.append(2)q2.append(3)print(q2) # deque([1, 2, 3], maxlen=3)q2.append(4)print(q2) # deque([2, 3, 4], maxlen=3)q2.append(5)print(q2) # deque([3, 4, 5], maxlen=3)q2.append(6)print(q2) # deque([4, 5, 6], maxlen=3)# 可以看到最多容納三個,再添加的話那麼,會被擠掉。可以用來製作記錄,最多查看多少次等等try: q2.insert(1, "satori")except Exception as e: print(e) # deque already at its maximum size# 另外在滿了的時候,不可以通過insert插入值# 那麼appendleft可以嗎?我們來試試q2.appendleft("satori")print(q2) # deque([‘satori‘, 4, 5], maxlen=3)# 6沒有了# 可以看到,當從後面插入的時候(o(*////▽////*)q),那麼前面的會被擠掉# 從前面插入的時候(o(*////▽////*)q),後面會被擠掉# extend呢?q2.extend(["mashiro", "miku"])print(q2) # deque([5, ‘mashiro‘, ‘miku‘], maxlen=3)# 可以看到,satori和4沒有了,說明extend也是可以的# 同理extendleft也可以使用,這裡不再試了
Counter
from collections import Counter# 在defaultdict的時候,我們統計了列表裡面的值的個數# Counter可以做的更方便l = ["a", "b", "a", "c", "c", "a", "a"]c = Counter(l)print(c) # Counter({‘a‘: 4, ‘c‘: 2, ‘b‘: 1})# 結果直接統計出來了# 而且Counter對象是dict的一個子類,說明字典的api,Counter也可以使用print(c["a"]) # 4# 當然也可以轉化為字典print(dict(c)) # {‘a‘: 4, ‘b‘: 1, ‘c‘: 2}# 不僅是list,只要是可迭代對象都是可以的s = "aaaabbbccd"c2 = Counter(s)print(c2) # Counter({‘a‘: 4, ‘b‘: 3, ‘c‘: 2, ‘d‘: 1})# 上面也說了,Counter是dict的一個子類# 那麼Counter也可以使用update方法,而且更強大c2.update("abcd")print(c2) # Counter({‘a‘: 5, ‘b‘: 4, ‘c‘: 3, ‘d‘: 2})# 可以看到將abcd和上面的s進行一個合并的統計# 你以為強大就強大在這裡嗎?c2.update(["a", "b", "c", "d", "古明地盆"])print(c2) # Counter({‘a‘: 6, ‘b‘: 5, ‘c‘: 4, ‘d‘: 3, ‘古明地盆‘: 1})# 我還可以update一個列表,那麼列表裡面的元素會作為(古明地盆)一個整體統計# 此外update還可以接受一個Counterc3 = Counter("aaaaaaaaaaa")print(c3) # Counter({‘a‘: 11})c2.update(c3)print(c2) # Counter({‘a‘: 17, ‘b‘: 5, ‘c‘: 4, ‘d‘: 3, ‘古明地盆‘: 1})# 還有一個最重要的方法# 如果我們想要在c2中選出value最大的三個key該怎麼辦呢?# 直接實現會很麻煩,可以使用heapq,當然Counter底層也是調用了heapqimport heapqprint(heapq.nlargest(3, c2, key=lambda x: c2[x])) # [‘a‘, ‘b‘, ‘c‘]# 再來看看Counterprint(c2.most_common(3)) # [(‘a‘, 17), (‘b‘, 5), (‘c‘, 4)]# 會將key,和key對應的最大的value按照順序以列表嵌套元組的方式顯示出來,非常的直觀# 你以為Counter就到此為止了,確實目前來說已經夠用了# 但是還有一些黑科技print(c2) # Counter({‘a‘: 17, ‘b‘: 5, ‘c‘: 4, ‘d‘: 3, ‘古明地盆‘: 1})print(c3) # Counter({‘a‘: 11})print(c2 + c3) # Counter({‘a‘: 28, ‘b‘: 5, ‘c‘: 4, ‘d‘: 3, ‘古明地盆‘: 1})# c2 + c3,表示將兩者的結果進行組合,key相同,那麼將對應的value相加print(c2 - c3) #Counter({‘a‘: 6, ‘b‘: 5, ‘c‘: 4, ‘d‘: 3, ‘古明地盆‘: 1})# c2 - c3,表示如果c3中有c2的元素,就把該元素從c2當中減去,當然還有數量的問題# 既然如此,那麼Counter是否支援集合的操作呢?比如&|^等等# 我們來看看c4 = Counter("aabbbcc")c5 = Counter("bbccdd")print(c4) # Counter({‘b‘: 3, ‘a‘: 2, ‘c‘: 2})print(c5) # Counter({‘b‘: 2, ‘c‘: 2, ‘d‘: 2})# c4 & c5,和c4 + c5不同,這真的是在做交集,不會相加# 並且key相同的話,選擇value小的那一個print(c4 & c5) # Counter({‘b‘: 2, ‘c‘: 2})# key相同,也不會將value相加,而是選擇value較大的那一個print(c4 | c5) # Counter({‘b‘: 3, ‘a‘: 2, ‘c‘: 2, ‘d‘: 2})‘‘‘print(c4 ^ c5),Counter不支援^(也就是對稱差集)的操作,也沒什麼意義‘‘‘# 以上就是我能想到的Counter的全部內容了,也許還有一些方法沒有介紹到# 但是你會字典的那些方法的話,也肯定會Counter的那些方法# Counter最主要的概念和用法就說到這裡,個人認為應該就是夠用了
OrderedDict
from collections import OrderedDict# 從字面理解就知道是一個排好序的dict# 繼承自dict,所以dict有的api,它都有d = OrderedDict()d["a"] = 1d["e"] = 2d["c"] = 3print(d) # OrderedDict([(‘a‘, 1), (‘e‘, 2), (‘c‘, 3)])# 顯然和我們添加順序是一樣的# 除此之外再介紹一個api,move_to_endd.move_to_end("a") # 從名字也可以理解出,把a移到最後print(d) # OrderedDict([(‘e‘, 2), (‘c‘, 3), (‘a‘, 1)])# 其他的和字典類似,就不介紹了。
ChainMap
from collections import ChainMapd1 = {"a": 1, "b": 2}d2 = {"c": 2, "d": 2}d = ChainMap(d1, d2)for k, v in d.items(): print(k, v)‘‘‘c 2d 2a 1b 2‘‘‘# 因此ChainMap的作用就是將多個字典組合成一個字典# 如果多個字典,key重合了會怎麼樣?d3 = {"a": 1, "b": 2}d4 = {"b":3, "c": 4}d = ChainMap(d3, d4)for k, v in d.items(): print(k, v)‘‘‘a 1b 2c 4‘‘‘# 可以看到即使value不一樣,還是只列印了第一個# 這個方法比較像chainfrom itertools import chaina = [1, 2, 3]b = "abc"c = {1, 2, 3}d = {"name": "satori", "age": 15}for i in chain(a, b, c, d): print(i)‘‘‘123abc123nameage‘‘‘
python--collections